diff options
author | Valentin Popov <valentin@popov.link> | 2024-01-08 00:21:28 +0300 |
---|---|---|
committer | Valentin Popov <valentin@popov.link> | 2024-01-08 00:21:28 +0300 |
commit | 1b6a04ca5504955c571d1c97504fb45ea0befee4 (patch) | |
tree | 7579f518b23313e8a9748a88ab6173d5e030b227 /vendor/anstyle/src | |
parent | 5ecd8cf2cba827454317368b68571df0d13d7842 (diff) | |
download | fparkan-1b6a04ca5504955c571d1c97504fb45ea0befee4.tar.xz fparkan-1b6a04ca5504955c571d1c97504fb45ea0befee4.zip |
Initial vendor packages
Signed-off-by: Valentin Popov <valentin@popov.link>
Diffstat (limited to 'vendor/anstyle/src')
-rw-r--r-- | vendor/anstyle/src/color.rs | 611 | ||||
-rw-r--r-- | vendor/anstyle/src/effect.rs | 369 | ||||
-rw-r--r-- | vendor/anstyle/src/lib.rs | 59 | ||||
-rw-r--r-- | vendor/anstyle/src/macros.rs | 5 | ||||
-rw-r--r-- | vendor/anstyle/src/reset.rs | 22 | ||||
-rw-r--r-- | vendor/anstyle/src/style.rs | 398 |
6 files changed, 1464 insertions, 0 deletions
diff --git a/vendor/anstyle/src/color.rs b/vendor/anstyle/src/color.rs new file mode 100644 index 0000000..8dcf6ca --- /dev/null +++ b/vendor/anstyle/src/color.rs @@ -0,0 +1,611 @@ +/// Any ANSI color code scheme +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum Color { + Ansi(AnsiColor), + Ansi256(Ansi256Color), + Rgb(RgbColor), +} + +impl Color { + /// Create a [`Style`][crate::Style] with this as the foreground + #[inline] + pub fn on(self, background: impl Into<Color>) -> crate::Style { + crate::Style::new() + .fg_color(Some(self)) + .bg_color(Some(background.into())) + } + + /// Create a [`Style`][crate::Style] with this as the foreground + #[inline] + pub const fn on_default(self) -> crate::Style { + crate::Style::new().fg_color(Some(self)) + } + + /// Render the ANSI code for a foreground color + #[inline] + pub fn render_fg(self) -> impl core::fmt::Display + Copy + Clone { + match self { + Self::Ansi(color) => DisplayBuffer::default().write_str(color.as_fg_str()), + Self::Ansi256(color) => color.as_fg_buffer(), + Self::Rgb(color) => color.as_fg_buffer(), + } + } + + #[inline] + #[cfg(feature = "std")] + pub(crate) fn write_fg_to(self, write: &mut dyn std::io::Write) -> std::io::Result<()> { + let buffer = match self { + Self::Ansi(color) => DisplayBuffer::default().write_str(color.as_fg_str()), + Self::Ansi256(color) => color.as_fg_buffer(), + Self::Rgb(color) => color.as_fg_buffer(), + }; + buffer.write_to(write) + } + + /// Render the ANSI code for a background color + #[inline] + pub fn render_bg(self) -> impl core::fmt::Display + Copy + Clone { + match self { + Self::Ansi(color) => DisplayBuffer::default().write_str(color.as_bg_str()), + Self::Ansi256(color) => color.as_bg_buffer(), + Self::Rgb(color) => color.as_bg_buffer(), + } + } + + #[inline] + #[cfg(feature = "std")] + pub(crate) fn write_bg_to(self, write: &mut dyn std::io::Write) -> std::io::Result<()> { + let buffer = match self { + Self::Ansi(color) => DisplayBuffer::default().write_str(color.as_bg_str()), + Self::Ansi256(color) => color.as_bg_buffer(), + Self::Rgb(color) => color.as_bg_buffer(), + }; + buffer.write_to(write) + } + + #[inline] + pub(crate) fn render_underline(self) -> impl core::fmt::Display + Copy + Clone { + match self { + Self::Ansi(color) => color.as_underline_buffer(), + Self::Ansi256(color) => color.as_underline_buffer(), + Self::Rgb(color) => color.as_underline_buffer(), + } + } + + #[inline] + #[cfg(feature = "std")] + pub(crate) fn write_underline_to(self, write: &mut dyn std::io::Write) -> std::io::Result<()> { + let buffer = match self { + Self::Ansi(color) => color.as_underline_buffer(), + Self::Ansi256(color) => color.as_underline_buffer(), + Self::Rgb(color) => color.as_underline_buffer(), + }; + buffer.write_to(write) + } +} + +impl From<AnsiColor> for Color { + #[inline] + fn from(inner: AnsiColor) -> Self { + Self::Ansi(inner) + } +} + +impl From<Ansi256Color> for Color { + #[inline] + fn from(inner: Ansi256Color) -> Self { + Self::Ansi256(inner) + } +} + +impl From<RgbColor> for Color { + #[inline] + fn from(inner: RgbColor) -> Self { + Self::Rgb(inner) + } +} + +impl From<u8> for Color { + #[inline] + fn from(inner: u8) -> Self { + Self::Ansi256(inner.into()) + } +} + +impl From<(u8, u8, u8)> for Color { + #[inline] + fn from(inner: (u8, u8, u8)) -> Self { + Self::Rgb(inner.into()) + } +} + +/// Available 4-bit ANSI color palette codes +/// +/// The user's terminal defines the meaning of the each palette code. +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[repr(u8)] +pub enum AnsiColor { + /// Black: #0 (foreground code `30`, background code `40`). + Black, + + /// Red: #1 (foreground code `31`, background code `41`). + Red, + + /// Green: #2 (foreground code `32`, background code `42`). + Green, + + /// Yellow: #3 (foreground code `33`, background code `43`). + Yellow, + + /// Blue: #4 (foreground code `34`, background code `44`). + Blue, + + /// Magenta: #5 (foreground code `35`, background code `45`). + Magenta, + + /// Cyan: #6 (foreground code `36`, background code `46`). + Cyan, + + /// White: #7 (foreground code `37`, background code `47`). + White, + + /// Bright black: #0 (foreground code `90`, background code `100`). + BrightBlack, + + /// Bright red: #1 (foreground code `91`, background code `101`). + BrightRed, + + /// Bright green: #2 (foreground code `92`, background code `102`). + BrightGreen, + + /// Bright yellow: #3 (foreground code `93`, background code `103`). + BrightYellow, + + /// Bright blue: #4 (foreground code `94`, background code `104`). + BrightBlue, + + /// Bright magenta: #5 (foreground code `95`, background code `105`). + BrightMagenta, + + /// Bright cyan: #6 (foreground code `96`, background code `106`). + BrightCyan, + + /// Bright white: #7 (foreground code `97`, background code `107`). + BrightWhite, +} + +impl AnsiColor { + /// Create a [`Style`][crate::Style] with this as the foreground + #[inline] + pub fn on(self, background: impl Into<Color>) -> crate::Style { + crate::Style::new() + .fg_color(Some(self.into())) + .bg_color(Some(background.into())) + } + + /// Create a [`Style`][crate::Style] with this as the foreground + #[inline] + pub const fn on_default(self) -> crate::Style { + crate::Style::new().fg_color(Some(Color::Ansi(self))) + } + + /// Render the ANSI code for a foreground color + #[inline] + pub fn render_fg(self) -> impl core::fmt::Display + Copy + Clone { + self.as_fg_str() + } + + #[inline] + fn as_fg_str(&self) -> &'static str { + match self { + Self::Black => escape!("3", "0"), + Self::Red => escape!("3", "1"), + Self::Green => escape!("3", "2"), + Self::Yellow => escape!("3", "3"), + Self::Blue => escape!("3", "4"), + Self::Magenta => escape!("3", "5"), + Self::Cyan => escape!("3", "6"), + Self::White => escape!("3", "7"), + Self::BrightBlack => escape!("9", "0"), + Self::BrightRed => escape!("9", "1"), + Self::BrightGreen => escape!("9", "2"), + Self::BrightYellow => escape!("9", "3"), + Self::BrightBlue => escape!("9", "4"), + Self::BrightMagenta => escape!("9", "5"), + Self::BrightCyan => escape!("9", "6"), + Self::BrightWhite => escape!("9", "7"), + } + } + + /// Render the ANSI code for a background color + #[inline] + pub fn render_bg(self) -> impl core::fmt::Display + Copy + Clone { + self.as_bg_str() + } + + #[inline] + fn as_bg_str(&self) -> &'static str { + match self { + Self::Black => escape!("4", "0"), + Self::Red => escape!("4", "1"), + Self::Green => escape!("4", "2"), + Self::Yellow => escape!("4", "3"), + Self::Blue => escape!("4", "4"), + Self::Magenta => escape!("4", "5"), + Self::Cyan => escape!("4", "6"), + Self::White => escape!("4", "7"), + Self::BrightBlack => escape!("10", "0"), + Self::BrightRed => escape!("10", "1"), + Self::BrightGreen => escape!("10", "2"), + Self::BrightYellow => escape!("10", "3"), + Self::BrightBlue => escape!("10", "4"), + Self::BrightMagenta => escape!("10", "5"), + Self::BrightCyan => escape!("10", "6"), + Self::BrightWhite => escape!("10", "7"), + } + } + + #[inline] + fn as_underline_buffer(&self) -> DisplayBuffer { + // No per-color codes; must delegate to `Ansi256Color` + Ansi256Color::from(*self).as_underline_buffer() + } + + /// Change the color to/from bright + #[must_use] + #[inline] + pub fn bright(self, yes: bool) -> Self { + if yes { + match self { + Self::Black => Self::BrightBlack, + Self::Red => Self::BrightRed, + Self::Green => Self::BrightGreen, + Self::Yellow => Self::BrightYellow, + Self::Blue => Self::BrightBlue, + Self::Magenta => Self::BrightMagenta, + Self::Cyan => Self::BrightCyan, + Self::White => Self::BrightWhite, + Self::BrightBlack => self, + Self::BrightRed => self, + Self::BrightGreen => self, + Self::BrightYellow => self, + Self::BrightBlue => self, + Self::BrightMagenta => self, + Self::BrightCyan => self, + Self::BrightWhite => self, + } + } else { + match self { + Self::Black => self, + Self::Red => self, + Self::Green => self, + Self::Yellow => self, + Self::Blue => self, + Self::Magenta => self, + Self::Cyan => self, + Self::White => self, + Self::BrightBlack => Self::Black, + Self::BrightRed => Self::Red, + Self::BrightGreen => Self::Green, + Self::BrightYellow => Self::Yellow, + Self::BrightBlue => Self::Blue, + Self::BrightMagenta => Self::Magenta, + Self::BrightCyan => Self::Cyan, + Self::BrightWhite => Self::White, + } + } + } + + /// Report whether the color is bright + #[inline] + pub fn is_bright(self) -> bool { + match self { + Self::Black => false, + Self::Red => false, + Self::Green => false, + Self::Yellow => false, + Self::Blue => false, + Self::Magenta => false, + Self::Cyan => false, + Self::White => false, + Self::BrightBlack => true, + Self::BrightRed => true, + Self::BrightGreen => true, + Self::BrightYellow => true, + Self::BrightBlue => true, + Self::BrightMagenta => true, + Self::BrightCyan => true, + Self::BrightWhite => true, + } + } +} + +/// 256 (8-bit) color support +/// +/// - `0..16` are [`AnsiColor`] palette codes +/// - `0..232` map to [`RgbColor`] color values +/// - `232..` map to [`RgbColor`] gray-scale values +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[repr(transparent)] +pub struct Ansi256Color(pub u8); + +impl Ansi256Color { + /// Create a [`Style`][crate::Style] with this as the foreground + #[inline] + pub fn on(self, background: impl Into<Color>) -> crate::Style { + crate::Style::new() + .fg_color(Some(self.into())) + .bg_color(Some(background.into())) + } + + /// Create a [`Style`][crate::Style] with this as the foreground + #[inline] + pub const fn on_default(self) -> crate::Style { + crate::Style::new().fg_color(Some(Color::Ansi256(self))) + } + + #[inline] + pub const fn index(self) -> u8 { + self.0 + } + + #[inline] + pub const fn into_ansi(self) -> Option<AnsiColor> { + match self.index() { + 0 => Some(AnsiColor::Black), + 1 => Some(AnsiColor::Red), + 2 => Some(AnsiColor::Green), + 3 => Some(AnsiColor::Yellow), + 4 => Some(AnsiColor::Blue), + 5 => Some(AnsiColor::Magenta), + 6 => Some(AnsiColor::Cyan), + 7 => Some(AnsiColor::White), + 8 => Some(AnsiColor::BrightBlack), + 9 => Some(AnsiColor::BrightRed), + 10 => Some(AnsiColor::BrightGreen), + 11 => Some(AnsiColor::BrightYellow), + 12 => Some(AnsiColor::BrightBlue), + 13 => Some(AnsiColor::BrightMagenta), + 14 => Some(AnsiColor::BrightCyan), + 15 => Some(AnsiColor::BrightWhite), + _ => None, + } + } + + #[inline] + pub const fn from_ansi(color: AnsiColor) -> Self { + match color { + AnsiColor::Black => Self(0), + AnsiColor::Red => Self(1), + AnsiColor::Green => Self(2), + AnsiColor::Yellow => Self(3), + AnsiColor::Blue => Self(4), + AnsiColor::Magenta => Self(5), + AnsiColor::Cyan => Self(6), + AnsiColor::White => Self(7), + AnsiColor::BrightBlack => Self(8), + AnsiColor::BrightRed => Self(9), + AnsiColor::BrightGreen => Self(10), + AnsiColor::BrightYellow => Self(11), + AnsiColor::BrightBlue => Self(12), + AnsiColor::BrightMagenta => Self(13), + AnsiColor::BrightCyan => Self(14), + AnsiColor::BrightWhite => Self(15), + } + } + + /// Render the ANSI code for a foreground color + #[inline] + pub fn render_fg(self) -> impl core::fmt::Display + Copy + Clone { + self.as_fg_buffer() + } + + #[inline] + fn as_fg_buffer(&self) -> DisplayBuffer { + DisplayBuffer::default() + .write_str("\x1B[38;5;") + .write_code(self.index()) + .write_str("m") + } + + /// Render the ANSI code for a background color + #[inline] + pub fn render_bg(self) -> impl core::fmt::Display + Copy + Clone { + self.as_bg_buffer() + } + + #[inline] + fn as_bg_buffer(&self) -> DisplayBuffer { + DisplayBuffer::default() + .write_str("\x1B[48;5;") + .write_code(self.index()) + .write_str("m") + } + + #[inline] + fn as_underline_buffer(&self) -> DisplayBuffer { + DisplayBuffer::default() + .write_str("\x1B[58;5;") + .write_code(self.index()) + .write_str("m") + } +} + +impl From<u8> for Ansi256Color { + #[inline] + fn from(inner: u8) -> Self { + Self(inner) + } +} + +impl From<AnsiColor> for Ansi256Color { + #[inline] + fn from(inner: AnsiColor) -> Self { + Self::from_ansi(inner) + } +} + +/// 24-bit ANSI RGB color codes +#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct RgbColor(pub u8, pub u8, pub u8); + +impl RgbColor { + /// Create a [`Style`][crate::Style] with this as the foreground + #[inline] + pub fn on(self, background: impl Into<Color>) -> crate::Style { + crate::Style::new() + .fg_color(Some(self.into())) + .bg_color(Some(background.into())) + } + + /// Create a [`Style`][crate::Style] with this as the foreground + #[inline] + pub const fn on_default(self) -> crate::Style { + crate::Style::new().fg_color(Some(Color::Rgb(self))) + } + + #[inline] + pub const fn r(self) -> u8 { + self.0 + } + + #[inline] + pub const fn g(self) -> u8 { + self.1 + } + + #[inline] + pub const fn b(self) -> u8 { + self.2 + } + + /// Render the ANSI code for a foreground color + #[inline] + pub fn render_fg(self) -> impl core::fmt::Display + Copy + Clone { + self.as_fg_buffer() + } + + #[inline] + fn as_fg_buffer(&self) -> DisplayBuffer { + DisplayBuffer::default() + .write_str("\x1B[38;2;") + .write_code(self.r()) + .write_str(";") + .write_code(self.g()) + .write_str(";") + .write_code(self.b()) + .write_str("m") + } + + /// Render the ANSI code for a background color + #[inline] + pub fn render_bg(self) -> impl core::fmt::Display + Copy + Clone { + self.as_bg_buffer() + } + + #[inline] + fn as_bg_buffer(&self) -> DisplayBuffer { + DisplayBuffer::default() + .write_str("\x1B[48;2;") + .write_code(self.r()) + .write_str(";") + .write_code(self.g()) + .write_str(";") + .write_code(self.b()) + .write_str("m") + } + + #[inline] + fn as_underline_buffer(&self) -> DisplayBuffer { + DisplayBuffer::default() + .write_str("\x1B[58;2;") + .write_code(self.r()) + .write_str(";") + .write_code(self.g()) + .write_str(";") + .write_code(self.b()) + .write_str("m") + } +} + +impl From<(u8, u8, u8)> for RgbColor { + #[inline] + fn from(inner: (u8, u8, u8)) -> Self { + let (r, g, b) = inner; + Self(r, g, b) + } +} + +#[derive(Copy, Clone, Default, Debug)] +struct DisplayBuffer { + buffer: [u8; 19], + len: usize, +} + +impl DisplayBuffer { + #[must_use] + #[inline(never)] + fn write_str(mut self, part: &'static str) -> Self { + for (i, b) in part.as_bytes().iter().enumerate() { + self.buffer[self.len + i] = *b; + } + self.len += part.len(); + self + } + + #[must_use] + #[inline(never)] + fn write_code(mut self, code: u8) -> Self { + let c1: u8 = (code / 100) % 10; + let c2: u8 = (code / 10) % 10; + let c3: u8 = code % 10; + + let mut printed = true; + if c1 != 0 { + printed = true; + self.buffer[self.len] = b'0' + c1; + self.len += 1; + } + if c2 != 0 || printed { + self.buffer[self.len] = b'0' + c2; + self.len += 1; + } + // If we received a zero value we must still print a value. + self.buffer[self.len] = b'0' + c3; + self.len += 1; + + self + } + + #[inline] + fn as_str(&self) -> &str { + // SAFETY: Only `&str` can be written to the buffer + unsafe { core::str::from_utf8_unchecked(&self.buffer[0..self.len]) } + } + + #[inline] + #[cfg(feature = "std")] + fn write_to(self, write: &mut dyn std::io::Write) -> std::io::Result<()> { + write.write_all(self.as_str().as_bytes()) + } +} + +impl core::fmt::Display for DisplayBuffer { + #[inline] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + self.as_str().fmt(f) + } +} + +#[cfg(test)] +#[cfg(feature = "std")] +mod test { + use super::*; + + #[test] + fn max_display_buffer() { + let c = RgbColor(255, 255, 255); + let actual = c.render_fg().to_string(); + assert_eq!(actual, "\u{1b}[38;2;255;255;255m"); + } +} diff --git a/vendor/anstyle/src/effect.rs b/vendor/anstyle/src/effect.rs new file mode 100644 index 0000000..56b3e61 --- /dev/null +++ b/vendor/anstyle/src/effect.rs @@ -0,0 +1,369 @@ +/// A set of text effects +/// +/// # Examples +/// +/// ```rust +/// let effects = anstyle::Effects::BOLD | anstyle::Effects::UNDERLINE; +/// ``` +#[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct Effects(u16); + +impl Effects { + const PLAIN: Self = Effects(0); + + pub const BOLD: Self = Effects(1 << 0); + pub const DIMMED: Self = Effects(1 << 1); + /// Not widely supported. Sometimes treated as inverse or blink + pub const ITALIC: Self = Effects(1 << 2); + /// Style extensions exist for Kitty, VTE, mintty and iTerm2. + pub const UNDERLINE: Self = Effects(1 << 3); + pub const DOUBLE_UNDERLINE: Self = Effects(1 << 4); + pub const CURLY_UNDERLINE: Self = Effects(1 << 5); + pub const DOTTED_UNDERLINE: Self = Effects(1 << 6); + pub const DASHED_UNDERLINE: Self = Effects(1 << 7); + pub const BLINK: Self = Effects(1 << 8); + /// Swap foreground and background colors; inconsistent emulation + pub const INVERT: Self = Effects(1 << 9); + pub const HIDDEN: Self = Effects(1 << 10); + /// Characters legible but marked as if for deletion. Not supported in Terminal.app + pub const STRIKETHROUGH: Self = Effects(1 << 11); + + /// No effects enabled + /// + /// # Examples + /// + /// ```rust + /// let effects = anstyle::Effects::new(); + /// ``` + #[inline] + pub const fn new() -> Self { + Self::PLAIN + } + + /// Check if no effects are enabled + /// + /// # Examples + /// + /// ```rust + /// let effects = anstyle::Effects::new(); + /// assert!(effects.is_plain()); + /// + /// let effects = anstyle::Effects::BOLD | anstyle::Effects::UNDERLINE; + /// assert!(!effects.is_plain()); + /// ``` + #[inline] + pub const fn is_plain(self) -> bool { + self.0 == Self::PLAIN.0 + } + + /// Returns `true` if all of the effects in `other` are contained within `self`. + /// + /// # Examples + /// + /// ```rust + /// let effects = anstyle::Effects::BOLD | anstyle::Effects::UNDERLINE; + /// assert!(effects.contains(anstyle::Effects::BOLD)); + /// + /// let effects = anstyle::Effects::new(); + /// assert!(!effects.contains(anstyle::Effects::BOLD)); + /// ``` + #[inline(always)] + pub const fn contains(self, other: Effects) -> bool { + (other.0 & self.0) == other.0 + } + + /// Inserts the specified effects in-place. + /// + /// # Examples + /// + /// ```rust + /// let effects = anstyle::Effects::new().insert(anstyle::Effects::new()); + /// assert!(effects.is_plain()); + /// + /// let effects = anstyle::Effects::new().insert(anstyle::Effects::BOLD); + /// assert!(effects.contains(anstyle::Effects::BOLD)); + /// ``` + #[inline(always)] + #[must_use] + pub const fn insert(mut self, other: Effects) -> Self { + self.0 |= other.0; + self + } + + /// Removes the specified effects in-place. + /// + /// # Examples + /// + /// ```rust + /// let effects = (anstyle::Effects::BOLD | anstyle::Effects::UNDERLINE).remove(anstyle::Effects::BOLD); + /// assert!(!effects.contains(anstyle::Effects::BOLD)); + /// assert!(effects.contains(anstyle::Effects::UNDERLINE)); + /// ``` + #[inline(always)] + #[must_use] + pub const fn remove(mut self, other: Effects) -> Self { + self.0 &= !other.0; + self + } + + /// Reset all effects in-place + /// ```rust + /// let effects = (anstyle::Effects::BOLD | anstyle::Effects::UNDERLINE).clear(); + /// assert!(!effects.contains(anstyle::Effects::BOLD)); + /// assert!(!effects.contains(anstyle::Effects::UNDERLINE)); + /// ``` + #[inline(always)] + #[must_use] + pub const fn clear(self) -> Self { + Self::new() + } + + /// Enable or disable the specified effects depending on the passed value. + /// + /// # Examples + /// + /// ```rust + /// let effects = anstyle::Effects::new().set(anstyle::Effects::BOLD, true); + /// assert!(effects.contains(anstyle::Effects::BOLD)); + /// ``` + #[inline] + #[must_use] + pub const fn set(self, other: Self, enable: bool) -> Self { + if enable { + self.insert(other) + } else { + self.remove(other) + } + } + + /// Iterate over enabled effects + #[inline(always)] + pub fn iter(self) -> EffectIter { + EffectIter { + index: 0, + effects: self, + } + } + + /// Iterate over enabled effect indices + #[inline(always)] + pub(crate) fn index_iter(self) -> EffectIndexIter { + EffectIndexIter { + index: 0, + effects: self, + } + } + + /// Render the ANSI code + #[inline] + pub fn render(self) -> impl core::fmt::Display + Copy + Clone { + EffectsDisplay(self) + } + + #[inline] + #[cfg(feature = "std")] + pub(crate) fn write_to(self, write: &mut dyn std::io::Write) -> std::io::Result<()> { + for index in self.index_iter() { + write.write_all(METADATA[index].escape.as_bytes())?; + } + Ok(()) + } +} + +/// # Examples +/// +/// ```rust +/// let effects = anstyle::Effects::new(); +/// assert_eq!(format!("{:?}", effects), "Effects()"); +/// +/// let effects = anstyle::Effects::BOLD | anstyle::Effects::UNDERLINE; +/// assert_eq!(format!("{:?}", effects), "Effects(BOLD | UNDERLINE)"); +/// ``` +impl core::fmt::Debug for Effects { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "Effects(")?; + for (i, index) in self.index_iter().enumerate() { + if i != 0 { + write!(f, " | ")?; + } + write!(f, "{}", METADATA[index].name)?; + } + write!(f, ")")?; + Ok(()) + } +} + +/// # Examples +/// +/// ```rust +/// let effects = anstyle::Effects::BOLD | anstyle::Effects::UNDERLINE; +/// assert_eq!(format!("{:?}", effects), "Effects(BOLD | UNDERLINE)"); +/// ``` +impl core::ops::BitOr for Effects { + type Output = Self; + + #[inline(always)] + fn bitor(self, rhs: Self) -> Self { + self.insert(rhs) + } +} + +/// # Examples +/// +/// ```rust +/// let mut effects = anstyle::Effects::BOLD; +/// effects |= anstyle::Effects::UNDERLINE; +/// assert_eq!(format!("{:?}", effects), "Effects(BOLD | UNDERLINE)"); +/// ``` +impl core::ops::BitOrAssign for Effects { + #[inline] + fn bitor_assign(&mut self, other: Self) { + *self = self.insert(other); + } +} + +/// # Examples +/// +/// ```rust +/// let effects = (anstyle::Effects::BOLD | anstyle::Effects::UNDERLINE) - anstyle::Effects::BOLD; +/// assert_eq!(format!("{:?}", effects), "Effects(UNDERLINE)"); +/// ``` +impl core::ops::Sub for Effects { + type Output = Self; + + #[inline] + fn sub(self, other: Self) -> Self { + self.remove(other) + } +} + +/// # Examples +/// +/// ```rust +/// let mut effects = anstyle::Effects::BOLD | anstyle::Effects::UNDERLINE; +/// effects -= anstyle::Effects::BOLD; +/// assert_eq!(format!("{:?}", effects), "Effects(UNDERLINE)"); +/// ``` +impl core::ops::SubAssign for Effects { + #[inline] + fn sub_assign(&mut self, other: Self) { + *self = self.remove(other); + } +} + +pub(crate) struct Metadata { + pub(crate) name: &'static str, + pub(crate) escape: &'static str, +} + +pub(crate) const METADATA: [Metadata; 12] = [ + Metadata { + name: "BOLD", + escape: escape!("1"), + }, + Metadata { + name: "DIMMED", + escape: escape!("2"), + }, + Metadata { + name: "ITALIC", + escape: escape!("3"), + }, + Metadata { + name: "UNDERLINE", + escape: escape!("4"), + }, + Metadata { + name: "DOUBLE_UNDERLINE", + escape: escape!("21"), + }, + Metadata { + name: "CURLY_UNDERLINE", + escape: escape!("4:3"), + }, + Metadata { + name: "DOTTED_UNDERLINE", + escape: escape!("4:4"), + }, + Metadata { + name: "DASHED_UNDERLINE", + escape: escape!("4:5"), + }, + Metadata { + name: "BLINK", + escape: escape!("5"), + }, + Metadata { + name: "INVERT", + escape: escape!("7"), + }, + Metadata { + name: "HIDDEN", + escape: escape!("8"), + }, + Metadata { + name: "STRIKETHROUGH", + escape: escape!("9"), + }, +]; + +#[derive(Copy, Clone, Default, Debug)] +struct EffectsDisplay(Effects); + +impl core::fmt::Display for EffectsDisplay { + #[inline] + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + for index in self.0.index_iter() { + METADATA[index].escape.fmt(f)?; + } + Ok(()) + } +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct EffectIter { + index: usize, + effects: Effects, +} + +impl Iterator for EffectIter { + type Item = Effects; + + fn next(&mut self) -> Option<Self::Item> { + while self.index < METADATA.len() { + let index = self.index; + self.index += 1; + + let effect = Effects(1 << index); + if self.effects.contains(effect) { + return Some(effect); + } + } + + None + } +} + +#[derive(Clone, Debug, PartialEq, Eq)] +pub(crate) struct EffectIndexIter { + index: usize, + effects: Effects, +} + +impl Iterator for EffectIndexIter { + type Item = usize; + + fn next(&mut self) -> Option<Self::Item> { + while self.index < METADATA.len() { + let index = self.index; + self.index += 1; + + let effect = Effects(1 << index); + if self.effects.contains(effect) { + return Some(index); + } + } + + None + } +} diff --git a/vendor/anstyle/src/lib.rs b/vendor/anstyle/src/lib.rs new file mode 100644 index 0000000..41b7174 --- /dev/null +++ b/vendor/anstyle/src/lib.rs @@ -0,0 +1,59 @@ +//! ANSI Text Styling +//! +//! *A portmanteau of "ansi style"* +//! +//! `anstyle` provides core types describing [ANSI styling escape +//! codes](https://en.wikipedia.org/wiki/ANSI_escape_code) for interoperability +//! between crates. +//! +//! Example use cases: +//! - An argument parser allowing callers to define the colors used in the help-output without +//! putting the text formatting crate in the public API +//! - A style description parser that can work with any text formatting crate +//! +//! Priorities: +//! 1. API stability +//! 2. Low compile-time and binary-size overhead +//! 3. `const` friendly API for callers to statically define their stylesheet +//! +//! For integration with text styling crate, see: +//! - [anstyle-ansi-term](https://docs.rs/anstyle-ansi-term) +//! - [anstyle-crossterm](https://docs.rs/anstyle-crossterm) +//! - [anstyle-owo-colors](https://docs.rs/anstyle-owo-colors) +//! - [anstyle-termcolor](https://docs.rs/anstyle-termcolor) +//! - [anstyle-yansi](https://docs.rs/anstyle-yansi) +//! +//! User-styling parsers: +//! - [anstyle-git](https://docs.rs/anstyle-git): Parse Git style descriptions +//! - [anstyle-ls](https://docs.rs/anstyle-ls): Parse LS_COLORS style descriptions +//! +//! Convert to other formats +//! - [anstream](https://docs.rs/anstream): A simple cross platform library for writing colored text to a terminal +//! - [anstyle-roff](https://docs.rs/anstyle-roff): For converting to ROFF +//! +//! Utilities +//! - [anstyle-lossy](https://docs.rs/anstyle-lossy): Convert between `anstyle::Color` types +//! - [anstyle-parse](https://docs.rs/anstyle-parse): Parsing ANSI Style Escapes +//! - [anstyle-wincon](https://docs.rs/anstyle-wincon): Styling legacy Microsoft terminals +//! +//! # Examples +//! +//! The core type is [`Style`]: +//! ```rust +//! let style = anstyle::Style::new().bold(); +//! ``` + +#![cfg_attr(not(feature = "std"), no_std)] + +#[macro_use] +mod macros; + +mod color; +mod effect; +mod reset; +mod style; + +pub use color::*; +pub use effect::*; +pub use reset::*; +pub use style::*; diff --git a/vendor/anstyle/src/macros.rs b/vendor/anstyle/src/macros.rs new file mode 100644 index 0000000..f19666e --- /dev/null +++ b/vendor/anstyle/src/macros.rs @@ -0,0 +1,5 @@ +macro_rules! escape { + ($($inner:expr),*) => { + concat!("\x1B[", $($inner),*, "m") + }; +} diff --git a/vendor/anstyle/src/reset.rs b/vendor/anstyle/src/reset.rs new file mode 100644 index 0000000..c8c2140 --- /dev/null +++ b/vendor/anstyle/src/reset.rs @@ -0,0 +1,22 @@ +/// Reset terminal formatting +#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct Reset; + +impl Reset { + /// Render the ANSI code + #[inline] + pub fn render(self) -> impl core::fmt::Display + Copy + Clone { + ResetDisplay + } +} + +#[derive(Copy, Clone, Default, Debug)] +struct ResetDisplay; + +impl core::fmt::Display for ResetDisplay { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + RESET.fmt(f) + } +} + +pub(crate) const RESET: &str = "\x1B[0m"; diff --git a/vendor/anstyle/src/style.rs b/vendor/anstyle/src/style.rs new file mode 100644 index 0000000..f4da242 --- /dev/null +++ b/vendor/anstyle/src/style.rs @@ -0,0 +1,398 @@ +use crate::reset::RESET; + +/// ANSI Text styling +/// +/// # Examples +/// +/// ```rust +/// let style = anstyle::Style::new().bold(); +/// ``` +#[derive(Copy, Clone, Default, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct Style { + fg: Option<crate::Color>, + bg: Option<crate::Color>, + underline: Option<crate::Color>, + effects: crate::Effects, +} + +/// # Core +impl Style { + /// No effects enabled + /// + /// # Examples + /// + /// ```rust + /// let style = anstyle::Style::new(); + /// ``` + #[inline] + pub const fn new() -> Self { + Self { + fg: None, + bg: None, + underline: None, + effects: crate::Effects::new(), + } + } + + /// Set foreground color + /// + /// # Examples + /// + /// ```rust + /// let style = anstyle::Style::new().fg_color(Some(anstyle::AnsiColor::Red.into())); + /// ``` + #[must_use] + #[inline] + pub const fn fg_color(mut self, fg: Option<crate::Color>) -> Self { + self.fg = fg; + self + } + + /// Set background color + /// + /// # Examples + /// + /// ```rust + /// let style = anstyle::Style::new().bg_color(Some(anstyle::AnsiColor::Red.into())); + /// ``` + #[must_use] + #[inline] + pub const fn bg_color(mut self, bg: Option<crate::Color>) -> Self { + self.bg = bg; + self + } + + /// Set underline color + /// + /// # Examples + /// + /// ```rust + /// let style = anstyle::Style::new().underline_color(Some(anstyle::AnsiColor::Red.into())); + /// ``` + #[must_use] + #[inline] + pub const fn underline_color(mut self, underline: Option<crate::Color>) -> Self { + self.underline = underline; + self + } + + /// Set text effects + /// + /// # Examples + /// + /// ```rust + /// let style = anstyle::Style::new().effects(anstyle::Effects::BOLD | anstyle::Effects::UNDERLINE); + /// ``` + #[must_use] + #[inline] + pub const fn effects(mut self, effects: crate::Effects) -> Self { + self.effects = effects; + self + } + + /// Render the ANSI code + #[inline] + pub fn render(self) -> impl core::fmt::Display + Copy + Clone { + StyleDisplay(self) + } + + /// Write the ANSI code + #[inline] + #[cfg(feature = "std")] + pub fn write_to(self, write: &mut dyn std::io::Write) -> std::io::Result<()> { + self.effects.write_to(write)?; + + if let Some(fg) = self.fg { + fg.write_fg_to(write)?; + } + + if let Some(bg) = self.bg { + bg.write_bg_to(write)?; + } + + if let Some(underline) = self.underline { + underline.write_underline_to(write)?; + } + + Ok(()) + } + + /// Renders the relevant [`Reset`][crate::Reset] code + /// + /// Unlike [`Reset::render`][crate::Reset::render], this will elide the code if there is nothing to reset. + #[inline] + pub fn render_reset(self) -> impl core::fmt::Display + Copy + Clone { + if self != Self::new() { + RESET + } else { + "" + } + } + + /// Write the relevant [`Reset`][crate::Reset] code + /// + /// Unlike [`Reset::render`][crate::Reset::render], this will elide the code if there is nothing to reset. + #[inline] + #[cfg(feature = "std")] + pub fn write_reset_to(self, write: &mut dyn std::io::Write) -> std::io::Result<()> { + if self != Self::new() { + write.write_all(RESET.as_bytes()) + } else { + Ok(()) + } + } +} + +/// # Convenience +impl Style { + /// Apply `bold` effect + /// + /// # Examples + /// + /// ```rust + /// let style = anstyle::Style::new().bold(); + /// ``` + #[must_use] + #[inline] + pub const fn bold(mut self) -> Self { + self.effects = self.effects.insert(crate::Effects::BOLD); + self + } + + /// Apply `dimmed` effect + /// + /// # Examples + /// + /// ```rust + /// let style = anstyle::Style::new().dimmed(); + /// ``` + #[must_use] + #[inline] + pub const fn dimmed(mut self) -> Self { + self.effects = self.effects.insert(crate::Effects::DIMMED); + self + } + + /// Apply `italic` effect + /// + /// # Examples + /// + /// ```rust + /// let style = anstyle::Style::new().italic(); + /// ``` + #[must_use] + #[inline] + pub const fn italic(mut self) -> Self { + self.effects = self.effects.insert(crate::Effects::ITALIC); + self + } + + /// Apply `underline` effect + /// + /// # Examples + /// + /// ```rust + /// let style = anstyle::Style::new().underline(); + /// ``` + #[must_use] + #[inline] + pub const fn underline(mut self) -> Self { + self.effects = self.effects.insert(crate::Effects::UNDERLINE); + self + } + + /// Apply `blink` effect + /// + /// # Examples + /// + /// ```rust + /// let style = anstyle::Style::new().blink(); + /// ``` + #[must_use] + #[inline] + pub const fn blink(mut self) -> Self { + self.effects = self.effects.insert(crate::Effects::BLINK); + self + } + + /// Apply `invert` effect + /// + /// # Examples + /// + /// ```rust + /// let style = anstyle::Style::new().invert(); + /// ``` + #[must_use] + #[inline] + pub const fn invert(mut self) -> Self { + self.effects = self.effects.insert(crate::Effects::INVERT); + self + } + + /// Apply `hidden` effect + /// + /// # Examples + /// + /// ```rust + /// let style = anstyle::Style::new().hidden(); + /// ``` + #[must_use] + #[inline] + pub const fn hidden(mut self) -> Self { + self.effects = self.effects.insert(crate::Effects::HIDDEN); + self + } + + /// Apply `strikethrough` effect + /// + /// # Examples + /// + /// ```rust + /// let style = anstyle::Style::new().strikethrough(); + /// ``` + #[must_use] + #[inline] + pub const fn strikethrough(mut self) -> Self { + self.effects = self.effects.insert(crate::Effects::STRIKETHROUGH); + self + } +} + +/// # Reflection +impl Style { + #[inline] + pub const fn get_fg_color(self) -> Option<crate::Color> { + self.fg + } + + #[inline] + pub const fn get_bg_color(self) -> Option<crate::Color> { + self.bg + } + + #[inline] + pub const fn get_underline_color(self) -> Option<crate::Color> { + self.underline + } + + #[inline] + pub const fn get_effects(self) -> crate::Effects { + self.effects + } + + /// Check if no effects are enabled + #[inline] + pub const fn is_plain(self) -> bool { + self.fg.is_none() + && self.bg.is_none() + && self.underline.is_none() + && self.effects.is_plain() + } +} + +/// # Examples +/// +/// ```rust +/// let style: anstyle::Style = anstyle::Effects::BOLD.into(); +/// ``` +impl From<crate::Effects> for Style { + #[inline] + fn from(effects: crate::Effects) -> Self { + Self::new().effects(effects) + } +} + +/// # Examples +/// +/// ```rust +/// let style = anstyle::Style::new() | anstyle::Effects::BOLD.into(); +/// ``` +impl core::ops::BitOr<crate::Effects> for Style { + type Output = Self; + + #[inline(always)] + fn bitor(mut self, rhs: crate::Effects) -> Self { + self.effects |= rhs; + self + } +} + +/// # Examples +/// +/// ```rust +/// let mut style = anstyle::Style::new(); +/// style |= anstyle::Effects::BOLD.into(); +/// ``` +impl core::ops::BitOrAssign<crate::Effects> for Style { + #[inline] + fn bitor_assign(&mut self, other: crate::Effects) { + self.effects |= other; + } +} + +/// # Examples +/// +/// ```rust +/// let style = anstyle::Style::new().bold().underline() - anstyle::Effects::BOLD.into(); +/// ``` +impl core::ops::Sub<crate::Effects> for Style { + type Output = Self; + + #[inline] + fn sub(mut self, other: crate::Effects) -> Self { + self.effects -= other; + self + } +} + +/// # Examples +/// +/// ```rust +/// let mut style = anstyle::Style::new().bold().underline(); +/// style -= anstyle::Effects::BOLD.into(); +/// ``` +impl core::ops::SubAssign<crate::Effects> for Style { + #[inline] + fn sub_assign(&mut self, other: crate::Effects) { + self.effects -= other; + } +} + +/// # Examples +/// +/// ```rust +/// let effects = anstyle::Effects::BOLD; +/// assert_eq!(anstyle::Style::new().effects(effects), effects); +/// assert_ne!(anstyle::Effects::UNDERLINE | effects, effects); +/// assert_ne!(anstyle::RgbColor(0, 0, 0).on_default() | effects, effects); +/// ``` +impl core::cmp::PartialEq<crate::Effects> for Style { + #[inline] + fn eq(&self, other: &crate::Effects) -> bool { + let other = Self::from(*other); + *self == other + } +} + +#[derive(Copy, Clone, Default, Debug)] +struct StyleDisplay(Style); + +impl core::fmt::Display for StyleDisplay { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + self.0.effects.render().fmt(f)?; + + if let Some(fg) = self.0.fg { + fg.render_fg().fmt(f)?; + } + + if let Some(bg) = self.0.bg { + bg.render_bg().fmt(f)?; + } + + if let Some(underline) = self.0.underline { + underline.render_underline().fmt(f)?; + } + + Ok(()) + } +} |