diff options
Diffstat (limited to 'vendor/anstyle/src/style.rs')
-rw-r--r-- | vendor/anstyle/src/style.rs | 398 |
1 files changed, 398 insertions, 0 deletions
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(()) + } +} |