diff --git a/src/lib.rs b/src/lib.rs index 41e88280..ff3f04ed 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -175,7 +175,7 @@ //! use std::io::{stdout, Write}; //! use crossterm::{ //! ExecutableCommand, QueueableCommand, -//! terminal, cursor, style::{self, Colorize}, Result +//! terminal, cursor, style::{self, Stylize}, Result //! }; //! //! fn main() -> Result<()> { @@ -204,7 +204,7 @@ //! use std::io::{stdout, Write}; //! use crossterm::{ //! execute, queue, -//! style::{self, Colorize}, cursor, terminal, Result +//! style::{self, Stylize}, cursor, terminal, Result //! }; //! //! fn main() -> Result<()> { diff --git a/src/style.rs b/src/style.rs index 41978df5..5e129d91 100644 --- a/src/style.rs +++ b/src/style.rs @@ -50,10 +50,11 @@ //! //! Functions: //! -//! Using functions from [`Colorize`](trait.Colorize.html) on a `String` or `&'static str` to color it. +//! Using functions from [`Stylize`](crate::style::Stylize) on a `String` or `&'static str` to color +//! it. //! //! ```no_run -//! use crossterm::style::Colorize; +//! use crossterm::style::Stylize; //! //! println!("{}", "Red foreground color & blue background.".red().on_blue()); //! ``` @@ -86,10 +87,11 @@ //! //! Functions: //! -//! Using [`Styler`](trait.Styler.html) functions on a `String` or `&'static str` to set attributes to it. +//! Using [`Stylize`](crate::style::Stylize) functions on a `String` or `&'static str` to set +//! attributes to it. //! //! ```no_run -//! use crossterm::style::Styler; +//! use crossterm::style::Stylize; //! //! println!("{}", "Bold".bold()); //! println!("{}", "Underlined".underlined()); @@ -115,6 +117,7 @@ use std::{ fmt::{self, Display}, }; +use crate::command::execute_fmt; #[cfg(windows)] use crate::Result; use crate::{csi, impl_display, Command}; @@ -123,17 +126,15 @@ pub use self::{ attributes::Attributes, content_style::ContentStyle, styled_content::StyledContent, - traits::{Colorize, Styler}, + stylize::Stylize, types::{Attribute, Color, Colored, Colors}, }; -#[macro_use] -mod macros; mod attributes; mod content_style; mod styled_content; +mod stylize; mod sys; -mod traits; mod types; /// Creates a `StyledContent`. @@ -145,7 +146,7 @@ mod types; /// # Examples /// /// ```no_run -/// use crossterm::style::{style, Color}; +/// use crossterm::style::{style, Stylize, Color}; /// /// let styled_content = style("Blue colored text on yellow background") /// .with(Color::Blue) @@ -157,24 +158,6 @@ pub fn style(val: D) -> StyledContent { ContentStyle::new().apply(val) } -impl_colorize!(String); -impl_colorize!(char); - -// We do actually need the parentheses here because the macro doesn't work without them otherwise -// This is probably a bug somewhere in the compiler, but it isn't that big a deal. -#[allow(unused_parens)] -impl<'a> Colorize<&'a str> for &'a str { - impl_colorize_callback!(def_color_base!((&'a str))); -} - -impl_styler!(String); -impl_styler!(char); - -#[allow(unused_parens)] -impl<'a> Styler<&'a str> for &'a str { - impl_styler_callback!(def_attr_base!((&'a str))); -} - /// Returns available color count. /// /// # Notes @@ -342,7 +325,44 @@ pub struct PrintStyledContent(pub StyledContent); impl Command for PrintStyledContent { fn write_ansi(&self, f: &mut impl fmt::Write) -> fmt::Result { - write!(f, "{}", self.0) + let style = self.0.style(); + + let mut reset_background = false; + let mut reset_foreground = false; + let mut reset = false; + + if let Some(bg) = style.background_color { + execute_fmt(f, SetBackgroundColor(bg)).map_err(|_| fmt::Error)?; + reset_background = true; + } + if let Some(fg) = style.foreground_color { + execute_fmt(f, SetForegroundColor(fg)).map_err(|_| fmt::Error)?; + reset_foreground = true; + } + + if !style.attributes.is_empty() { + execute_fmt(f, SetAttributes(style.attributes)).map_err(|_| fmt::Error)?; + reset = true; + } + + write!(f, "{}", self.0.content())?; + + if reset { + // NOTE: This will reset colors even though self has no colors, hence produce unexpected + // resets. + // TODO: reset the set attributes only. + execute_fmt(f, ResetColor).map_err(|_| fmt::Error)?; + } else { + // NOTE: Since the above bug, we do not need to reset colors when we reset attributes. + if reset_background { + execute_fmt(f, SetBackgroundColor(Color::Reset)).map_err(|_| fmt::Error)?; + } + if reset_foreground { + execute_fmt(f, SetForegroundColor(Color::Reset)).map_err(|_| fmt::Error)?; + } + } + + Ok(()) } #[cfg(windows)] diff --git a/src/style/content_style.rs b/src/style/content_style.rs index 41d52b4a..45b3b1c5 100644 --- a/src/style/content_style.rs +++ b/src/style/content_style.rs @@ -2,7 +2,7 @@ use std::fmt::Display; -use crate::style::{Attribute, Attributes, Color, StyledContent}; +use crate::style::{Attributes, Color, StyledContent}; /// The style that can be put on content. #[derive(Debug, Copy, Clone, Default, PartialEq, Eq)] @@ -27,62 +27,15 @@ impl ContentStyle { pub fn new() -> ContentStyle { ContentStyle::default() } +} - /// Sets the background color. - #[inline] - pub fn background(self, color: Color) -> ContentStyle { - Self { - background_color: Some(color), - ..self - } - } - - /// Sets the foreground color. - #[inline] - pub fn foreground(self, color: Color) -> ContentStyle { - Self { - foreground_color: Some(color), - ..self - } - } - - /// Adds the attribute. - /// - /// You can add more attributes by calling this method multiple times. - #[inline] - pub fn attribute(mut self, attr: Attribute) -> ContentStyle { - self.attributes.set(attr); +impl AsRef for ContentStyle { + fn as_ref(&self) -> &Self { self } } - -#[cfg(test)] -mod tests { - use crate::style::{Attribute, Color, ContentStyle}; - - #[test] - fn test_set_fg_bg_add_attr() { - let content_style = ContentStyle::new() - .foreground(Color::Blue) - .background(Color::Red) - .attribute(Attribute::Bold); - - assert_eq!(content_style.foreground_color, Some(Color::Blue)); - assert_eq!(content_style.background_color, Some(Color::Red)); - assert!(content_style.attributes.has(Attribute::Bold)); - } - - #[test] - fn test_apply_content_style_to_text() { - let content_style = ContentStyle::new() - .foreground(Color::Blue) - .background(Color::Red) - .attribute(Attribute::Reset); - - let styled_content = content_style.apply("test"); - - assert_eq!(styled_content.style().foreground_color, Some(Color::Blue)); - assert_eq!(styled_content.style().background_color, Some(Color::Red)); - assert!(styled_content.style().attributes.has(Attribute::Reset)); +impl AsMut for ContentStyle { + fn as_mut(&mut self) -> &mut Self { + self } } diff --git a/src/style/macros.rs b/src/style/macros.rs deleted file mode 100644 index 0b92d20e..00000000 --- a/src/style/macros.rs +++ /dev/null @@ -1,179 +0,0 @@ -//! Defines the macros for repetitive styling implementations - -// There's a single core set of macros structure here that's essentially repeated twice; once for -// implementing `Styler` and once for `Colorize`. We'll go through `Styler` as the example, knowing -// that `Colorize` works in precisely the same manner. -// -// There are four macros in each group. For `Styler`, they are: -// * def_attr_base, -// * def_attr_generic, -// * impl_styler_callback, -// * impl_styler -// -// Fundamentally, any implementation works in a similar fashion; many methods with near-identical -// bodies are grouped together. There are additionally two types of implementors: so-called "base" -// implementors (`char`, `String`, etc.) and a single "generic" implementor - 'StyledContent'. -// -// We can visualize the macro expansion with a sort of pipeline: -// -// /--------> def_attr_base -// [impl_styler ->] impl_styler_callback -// \--------> def_attr_generic -// -// The code-gen starts at 'impl_styler' for "base" implementors, and at 'impl_styler_callback' for -// `StyledContent`. From there, 'impl_styler_callback' either repeatedly calls 'def_attr_base' -// or 'def_attr_generic' - this is determined by the 'callback' argument. -// -// 'def_attr_base' is used to provide the method bodies for base types, and 'def_attr_generic' -// provides the method bodies for 'StyledContent'. - -//////////////////////////////////////////////////////////////////////////////// -// `Styler` macros // -//////////////////////////////////////////////////////////////////////////////// - -// Produces a single method for a "base" Styler implementation -// -// The first argument is the type for which Styler is being implemented. Because this is the same -// for all "base" types, we can collapse them into a single macro. -macro_rules! def_attr_base { - ($impl_ty:ty, $name:ident => $attr:path) => { - fn $name(self) -> StyledContent<$impl_ty> { - StyledContent::new( - ContentStyle { - attributes: $attr.into(), - ..Default::default() - }, - self, - ) - } - }; -} - -// Produces a single method within an implementation of Styler for 'StyledContent' -// -// We give it an empty argument at the start so that it has the same "signature" as -// 'def_attr_base', which takes a type as its first argument -macro_rules! def_attr_generic { - ((), $name:ident => $attr:path) => { - fn $name(self) -> StyledContent { - self.attribute($attr) - } - }; -} - -// Produces the set of methods inside the implementation, but not the outer block itself -// -// 'callback' should be either one of 'def_attr_base' or 'def_attr_generic'. Each expansion of -// 'callback' produces a single method with the name given by the second argument. -macro_rules! impl_styler_callback { - ($callback:ident!($args:tt)) => { - $callback!($args, reset => Attribute::Reset); - $callback!($args, bold => Attribute::Bold); - $callback!($args, underlined => Attribute::Underlined); - $callback!($args, reverse => Attribute::Reverse); - $callback!($args, dim => Attribute::Dim); - $callback!($args, italic => Attribute::Italic); - $callback!($args, negative => Attribute::Reverse); - $callback!($args, slow_blink => Attribute::SlowBlink); - $callback!($args, rapid_blink => Attribute::RapidBlink); - $callback!($args, hidden => Attribute::Hidden); - $callback!($args, crossed_out => Attribute::CrossedOut); - } -} - -// Produces the full implementation of Styler for "base" types -// -// This macro is mostly here for convenience; it's nice to not require writing out the -// `impl Styler<..> for ..` for each base type. -macro_rules! impl_styler { - ($impl_ty:ty) => { - impl Styler<$impl_ty> for $impl_ty { - impl_styler_callback!(def_attr_base!($impl_ty)); - } - }; -} - -//////////////////////////////////////////////////////////////////////////////// -// `Colorize` macros // -// // -// These are effectively the same as the `Styler` macros described above, so // -// not much detail is repeated here. Where above we have 'def_attr_*', there // -// is 'def_color_*' here, and 'impl_colorize' takes the place of // -// 'impl_styler'. // -//////////////////////////////////////////////////////////////////////////////// - -macro_rules! def_color_base { - ($color_ty:ty, $side:ident: $name:ident => $color:path) => { - fn $name(self) -> StyledContent<$color_ty> { - StyledContent::new( - ContentStyle { - $side: Some($color), - ..Default::default() - }, - self, - ) - } - }; -} - -macro_rules! def_color_generic { - ((), $side:ident: $name:ident => $color:path) => { - fn $name(self) -> StyledContent { - StyledContent::new( - ContentStyle { - $side: Some($color), - ..self.style - }, - self.content, - ) - } - }; -} - -macro_rules! impl_colorize_callback { - ($callback:ident!($args:tt)) => { - // foreground colors - $callback!($args, foreground_color: black => Color::Black); - $callback!($args, foreground_color: dark_grey => Color::DarkGrey); - $callback!($args, foreground_color: red => Color::Red); - $callback!($args, foreground_color: dark_red => Color::DarkRed); - $callback!($args, foreground_color: green => Color::Green); - $callback!($args, foreground_color: dark_green => Color::DarkGreen); - $callback!($args, foreground_color: yellow => Color::Yellow); - $callback!($args, foreground_color: dark_yellow => Color::DarkYellow); - $callback!($args, foreground_color: blue => Color::Blue); - $callback!($args, foreground_color: dark_blue => Color::DarkBlue); - $callback!($args, foreground_color: magenta => Color::Magenta); - $callback!($args, foreground_color: dark_magenta => Color::DarkMagenta); - $callback!($args, foreground_color: cyan => Color::Cyan); - $callback!($args, foreground_color: dark_cyan => Color::DarkCyan); - $callback!($args, foreground_color: white => Color::White); - $callback!($args, foreground_color: grey => Color::Grey); - - // background colors - $callback!($args, background_color: on_black => Color::Black); - $callback!($args, background_color: on_dark_grey => Color::DarkGrey); - $callback!($args, background_color: on_red => Color::Red); - $callback!($args, background_color: on_dark_red => Color::DarkRed); - $callback!($args, background_color: on_green => Color::Green); - $callback!($args, background_color: on_dark_green => Color::DarkGreen); - $callback!($args, background_color: on_yellow => Color::Yellow); - $callback!($args, background_color: on_dark_yellow => Color::DarkYellow); - $callback!($args, background_color: on_blue => Color::Blue); - $callback!($args, background_color: on_dark_blue => Color::DarkBlue); - $callback!($args, background_color: on_magenta => Color::Magenta); - $callback!($args, background_color: on_dark_magenta => Color::DarkMagenta); - $callback!($args, background_color: on_cyan => Color::Cyan); - $callback!($args, background_color: on_dark_cyan => Color::DarkCyan); - $callback!($args, background_color: on_white => Color::White); - $callback!($args, background_color: on_grey => Color::Grey); - }; -} - -macro_rules! impl_colorize { - ($impl_ty:ty) => { - impl Colorize<$impl_ty> for $impl_ty { - impl_colorize_callback!(def_color_base!($impl_ty)); - } - }; -} diff --git a/src/style/styled_content.rs b/src/style/styled_content.rs index bb959895..a511ed28 100644 --- a/src/style/styled_content.rs +++ b/src/style/styled_content.rs @@ -1,26 +1,17 @@ //! This module contains the logic to style some content. -use std::{ - fmt::{self, Display, Formatter}, - result, -}; +use std::fmt::{self, Display, Formatter}; -use crate::{ - command::execute_fmt, - style::{ - Attribute, Color, Colorize, ContentStyle, ResetColor, SetAttributes, SetBackgroundColor, - SetForegroundColor, Styler, - }, -}; +use super::{ContentStyle, PrintStyledContent}; /// The style with the content to be styled. /// /// # Examples /// /// ```rust -/// use crossterm::style::{style, Color, Attribute}; +/// use crossterm::style::{style, Color, Attribute, Stylize}; /// -/// let styled = style("Hello there") +/// let styled = "Hello there" /// .with(Color::Yellow) /// .on(Color::Blue) /// .attribute(Attribute::Bold); @@ -42,35 +33,6 @@ impl StyledContent { StyledContent { style, content } } - /// Sets the foreground color. - #[inline] - pub fn with(self, foreground_color: Color) -> StyledContent { - Self { - style: self.style.foreground(foreground_color), - ..self - } - } - - /// Sets the background color. - #[inline] - pub fn on(self, background_color: Color) -> StyledContent { - Self { - style: self.style.background(background_color), - ..self - } - } - - /// Adds the attribute. - /// - /// You can add more attributes by calling this method multiple times. - #[inline] - pub fn attribute(self, attr: Attribute) -> StyledContent { - Self { - style: self.style.attribute(attr), - ..self - } - } - /// Returns the content. #[inline] pub fn content(&self) -> &D { @@ -91,76 +53,25 @@ impl StyledContent { } } +impl AsRef for StyledContent { + fn as_ref(&self) -> &ContentStyle { + &self.style + } +} +impl AsMut for StyledContent { + fn as_mut(&mut self) -> &mut ContentStyle { + &mut self.style + } +} + impl Display for StyledContent { - fn fmt(&self, f: &mut Formatter<'_>) -> result::Result<(), fmt::Error> { - let mut reset_background = false; - let mut reset_foreground = false; - let mut reset = false; - - if let Some(bg) = self.style.background_color { - execute_fmt(f, SetBackgroundColor(bg)).map_err(|_| fmt::Error)?; - reset_background = true; - } - if let Some(fg) = self.style.foreground_color { - execute_fmt(f, SetForegroundColor(fg)).map_err(|_| fmt::Error)?; - reset_foreground = true; - } - - if !self.style.attributes.is_empty() { - execute_fmt(f, SetAttributes(self.style.attributes)).map_err(|_| fmt::Error)?; - reset = true; - } - - self.content.fmt(f)?; - - if reset { - // NOTE: This will reset colors even though self has no colors, hence produce unexpected - // resets. - // TODO: reset the set attributes only. - execute_fmt(f, ResetColor).map_err(|_| fmt::Error)?; - } else { - // NOTE: Since the above bug, we do not need to reset colors when we reset attributes. - if reset_background { - execute_fmt(f, SetBackgroundColor(Color::Reset)).map_err(|_| fmt::Error)?; - } - if reset_foreground { - execute_fmt(f, SetForegroundColor(Color::Reset)).map_err(|_| fmt::Error)?; - } - } - - Ok(()) - } -} - -impl Colorize for StyledContent { - impl_colorize_callback!(def_color_generic!(())); -} - -impl Styler for StyledContent { - impl_styler_callback!(def_attr_generic!(())); -} - -#[cfg(test)] -mod tests { - use super::{Attribute, Color, ContentStyle}; - - #[test] - fn test_set_fg_bg_add_attr() { - let style = ContentStyle::new() - .foreground(Color::Blue) - .background(Color::Red) - .attribute(Attribute::Bold); - - let mut styled_content = style.apply("test"); - - styled_content = styled_content - .with(Color::Green) - .on(Color::Magenta) - .attribute(Attribute::NoItalic); - - assert_eq!(styled_content.style.foreground_color, Some(Color::Green)); - assert_eq!(styled_content.style.background_color, Some(Color::Magenta)); - assert!(styled_content.style.attributes.has(Attribute::Bold)); - assert!(styled_content.style.attributes.has(Attribute::NoItalic)); + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + crate::command::execute_fmt( + f, + PrintStyledContent(StyledContent { + style: self.style, + content: &self.content, + }), + ) } } diff --git a/src/style/stylize.rs b/src/style/stylize.rs new file mode 100644 index 00000000..ae709a46 --- /dev/null +++ b/src/style/stylize.rs @@ -0,0 +1,182 @@ +use std::fmt::Display; + +use super::{style, Attribute, Color, ContentStyle, StyledContent}; + +macro_rules! stylize_method { + ($method_name:ident Attribute::$attribute:ident) => { + calculated_docs! { + #[doc = concat!( + "Applies the [`", + stringify!($attribute), + "`](Attribute::", + stringify!($attribute), + ") attribute to the text.", + )] + fn $method_name(self) -> Self::Styled { + self.attribute(Attribute::$attribute) + } + } + }; + ($method_name_fg:ident, $method_name_bg:ident Color::$color:ident) => { + calculated_docs! { + #[doc = concat!( + "Sets the foreground color to [`", + stringify!($color), + "`](Color::", + stringify!($color), + ")." + )] + fn $method_name_fg(self) -> Self::Styled { + self.with(Color::$color) + } + + #[doc = concat!( + "Sets the background color to [`", + stringify!($color), + "`](Color::", + stringify!($color), + ")." + )] + fn $method_name_bg(self) -> Self::Styled { + self.on(Color::$color) + } + } + }; +} + +/// Provides a set of methods to set attributes and colors. +/// +/// # Examples +/// +/// ```no_run +/// use crossterm::style::Stylize; +/// +/// println!("{}", "Bold text".bold()); +/// println!("{}", "Underlined text".underlined()); +/// println!("{}", "Negative text".negative()); +/// println!("{}", "Red on blue".red().on_blue()); +/// ``` +pub trait Stylize: Sized { + /// This type with styles applied. + type Styled: AsRef + AsMut; + + /// Styles this type. + fn stylize(self) -> Self::Styled; + + /// Sets the foreground color. + fn with(self, color: Color) -> Self::Styled { + let mut styled = self.stylize(); + styled.as_mut().foreground_color = Some(color); + styled + } + + /// Sets the background color. + fn on(self, color: Color) -> Self::Styled { + let mut styled = self.stylize(); + styled.as_mut().background_color = Some(color); + styled + } + + /// Styles the content with the attribute. + fn attribute(self, attr: Attribute) -> Self::Styled { + let mut styled = self.stylize(); + styled.as_mut().attributes.set(attr); + styled + } + + stylize_method!(reset Attribute::Reset); + stylize_method!(bold Attribute::Bold); + stylize_method!(underlined Attribute::Underlined); + stylize_method!(reverse Attribute::Reverse); + stylize_method!(dim Attribute::Dim); + stylize_method!(italic Attribute::Italic); + stylize_method!(negative Attribute::Reverse); + stylize_method!(slow_blink Attribute::SlowBlink); + stylize_method!(rapid_blink Attribute::RapidBlink); + stylize_method!(hidden Attribute::Hidden); + stylize_method!(crossed_out Attribute::CrossedOut); + + stylize_method!(black, on_black Color::Black); + stylize_method!(dark_grey, on_dark_grey Color::DarkGrey); + stylize_method!(red, on_red Color::Red); + stylize_method!(dark_red, on_dark_red Color::DarkRed); + stylize_method!(green, on_green Color::Green); + stylize_method!(dark_green, on_dark_green Color::DarkGreen); + stylize_method!(yellow, on_yellow Color::Yellow); + stylize_method!(dark_yellow, on_dark_yellow Color::DarkYellow); + stylize_method!(blue, on_blue Color::Blue); + stylize_method!(dark_blue, on_dark_blue Color::DarkBlue); + stylize_method!(magenta, on_magenta Color::Magenta); + stylize_method!(dark_magenta, on_dark_magenta Color::DarkMagenta); + stylize_method!(cyan, on_cyan Color::Cyan); + stylize_method!(dark_cyan, on_dark_cyan Color::DarkCyan); + stylize_method!(white, on_white Color::White); + stylize_method!(grey, on_grey Color::Grey); +} + +macro_rules! impl_stylize_for_display { + ($($t:ty),*) => { $( + impl Stylize for $t { + type Styled = StyledContent; + #[inline] + fn stylize(self) -> Self::Styled { + style(self) + } + } + )* } +} +impl_stylize_for_display!(String, char, &str); + +impl Stylize for ContentStyle { + type Styled = Self; + #[inline] + fn stylize(self) -> Self::Styled { + self + } +} +impl Stylize for StyledContent { + type Styled = StyledContent; + fn stylize(self) -> Self::Styled { + self + } +} + +// Workaround for https://github.com/rust-lang/rust/issues/78835 +macro_rules! calculated_docs { + ($(#[doc = $doc:expr] $item:item)*) => { $(#[doc = $doc] $item)* }; +} +// Remove once https://github.com/rust-lang/rust-clippy/issues/7106 stabilizes. +#[allow(clippy::single_component_path_imports)] +#[allow(clippy::useless_attribute)] +use calculated_docs; + +#[cfg(test)] +mod tests { + use super::super::{Attribute, Color, ContentStyle, Stylize}; + + #[test] + fn set_fg_bg_add_attr() { + let style = ContentStyle::new() + .with(Color::Blue) + .on(Color::Red) + .attribute(Attribute::Bold); + + assert_eq!(style.foreground_color, Some(Color::Blue)); + assert_eq!(style.background_color, Some(Color::Red)); + assert!(style.attributes.has(Attribute::Bold)); + + let mut styled_content = style.apply("test"); + + styled_content = styled_content + .with(Color::Green) + .on(Color::Magenta) + .attribute(Attribute::NoItalic); + + let style = styled_content.style(); + + assert_eq!(style.foreground_color, Some(Color::Green)); + assert_eq!(style.background_color, Some(Color::Magenta)); + assert!(style.attributes.has(Attribute::Bold)); + assert!(style.attributes.has(Attribute::NoItalic)); + } +} diff --git a/src/style/traits.rs b/src/style/traits.rs deleted file mode 100644 index d83e02a9..00000000 --- a/src/style/traits.rs +++ /dev/null @@ -1,81 +0,0 @@ -use std::fmt::Display; - -use super::StyledContent; - -/// Provides a set of methods to set the colors. -/// -/// Every method with the `on_` prefix sets the background color. All other methods set -/// the foreground color. -/// -/// Method names correspond to the [`Color`](enum.Color.html) enum variants. -/// -/// # Examples -/// -/// ```no_run -/// use crossterm::style::Colorize; -/// -/// let styled_text = "Red foreground color on blue background.".red().on_blue(); -/// println!("{}", styled_text); -/// ``` -pub trait Colorize { - fn black(self) -> StyledContent; - fn dark_grey(self) -> StyledContent; - fn red(self) -> StyledContent; - fn dark_red(self) -> StyledContent; - fn green(self) -> StyledContent; - fn dark_green(self) -> StyledContent; - fn yellow(self) -> StyledContent; - fn dark_yellow(self) -> StyledContent; - fn blue(self) -> StyledContent; - fn dark_blue(self) -> StyledContent; - fn magenta(self) -> StyledContent; - fn dark_magenta(self) -> StyledContent; - fn cyan(self) -> StyledContent; - fn dark_cyan(self) -> StyledContent; - fn white(self) -> StyledContent; - fn grey(self) -> StyledContent; - - fn on_black(self) -> StyledContent; - fn on_dark_grey(self) -> StyledContent; - fn on_red(self) -> StyledContent; - fn on_dark_red(self) -> StyledContent; - fn on_green(self) -> StyledContent; - fn on_dark_green(self) -> StyledContent; - fn on_yellow(self) -> StyledContent; - fn on_dark_yellow(self) -> StyledContent; - fn on_blue(self) -> StyledContent; - fn on_dark_blue(self) -> StyledContent; - fn on_magenta(self) -> StyledContent; - fn on_dark_magenta(self) -> StyledContent; - fn on_cyan(self) -> StyledContent; - fn on_dark_cyan(self) -> StyledContent; - fn on_white(self) -> StyledContent; - fn on_grey(self) -> StyledContent; -} - -/// Provides a set of methods to set the text attributes. -/// -/// Method names correspond to the [`Attribute`](enum.Attribute.html) enum variants. -/// -/// # Examples -/// -/// ```no_run -/// use crossterm::style::Styler; -/// -/// println!("{}", "Bold text".bold()); -/// println!("{}", "Underlined text".underlined()); -/// println!("{}", "Negative text".negative()); -/// ``` -pub trait Styler { - fn reset(self) -> StyledContent; - fn bold(self) -> StyledContent; - fn underlined(self) -> StyledContent; - fn reverse(self) -> StyledContent; - fn dim(self) -> StyledContent; - fn italic(self) -> StyledContent; - fn negative(self) -> StyledContent; - fn slow_blink(self) -> StyledContent; - fn rapid_blink(self) -> StyledContent; - fn hidden(self) -> StyledContent; - fn crossed_out(self) -> StyledContent; -} diff --git a/src/style/types/attribute.rs b/src/style/types/attribute.rs index 8a6095f4..f04eec9c 100644 --- a/src/style/types/attribute.rs +++ b/src/style/types/attribute.rs @@ -59,7 +59,7 @@ macro_rules! Attribute { /// Style existing text: /// /// ```no_run - /// use crossterm::style::Styler; + /// use crossterm::style::Stylize; /// /// println!("{}", "Bold text".bold()); /// println!("{}", "Underlined text".underlined());