diff --git a/CHANGELOG.md b/CHANGELOG.md index 8b0f08f..880f751 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,7 +14,12 @@ - Rename `ResetPos` to `ResetPosition` - Rename `SavePos` to `SavePosition` - Remove re-export cursor module types at root level, are now accessible from `crossterm::cursor` - + - `style module` + - Rename `ObjectStyle` to `ContentStyle`. Now full names are used for methods. + - Rename `StyledObject` to `StyledContent` and made members private. + - Rename `attr` method to `attribute`. + - Rename `Attribute::NoInverse` to `NoReverse` + # Version 0.12.1 - All the `crossterm_` crates code was moved to the `crossterm` crate diff --git a/README.md b/README.md index 561ad4e..5b285d3 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,6 @@ see [Tested Terminals](#tested-terminals) for more info). * [Tested Terminals](#tested-terminals) * [Getting Started](#getting-started) * [Feature Flags](#feature-flags) - * [`crossterm` vs `crossterm_*` crates](#crossterm-vs-crossterm_-crates) * [Other Resources](#other-resources) * [Used By](#used-by) * [Contributing](#contributing) diff --git a/src/crossterm.rs b/src/crossterm.rs index 8a8ad9c..a755f50 100644 --- a/src/crossterm.rs +++ b/src/crossterm.rs @@ -28,12 +28,12 @@ impl Crossterm { crate::style::TerminalColor::new() } - /// Creates a new `StyledObject`. + /// Creates a new `StyledContent`. #[cfg(feature = "style")] - pub fn style(&self, val: D) -> crate::style::StyledObject + pub fn style(&self, val: D) -> crate::style::StyledContent where D: Display + Clone, { - crate::style::ObjectStyle::new().apply_to(val) + crate::style::ContentStyle::new().apply(val) } } diff --git a/src/lib.rs b/src/lib.rs index e96369f..116c0be 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -177,8 +177,8 @@ pub use screen::{ }; #[cfg(feature = "style")] pub use style::{ - color, style, Attribute, Color, Colored, Colorize, ObjectStyle, PrintStyledFont, ResetColor, - SetAttr, SetBg, SetFg, StyledObject, Styler, TerminalColor, + color, style, Attribute, Color, Colored, Colorize, ContentStyle, PrintStyledFont, ResetColor, + SetAttr, SetBg, SetFg, StyledContent, Styler, TerminalColor, }; #[cfg(feature = "terminal")] pub use terminal::{terminal, Clear, ClearType, ScrollDown, ScrollUp, SetSize, Terminal}; diff --git a/src/style.rs b/src/style.rs index a486912..47b36ae 100644 --- a/src/style.rs +++ b/src/style.rs @@ -115,41 +115,41 @@ use crate::impl_display; use crate::utils::supports_ansi; use crate::utils::{Command, Result}; +pub use self::contentstyle::ContentStyle; pub use self::enums::{Attribute, Color, Colored}; -pub use self::objectstyle::ObjectStyle; -pub use self::styledobject::StyledObject; +pub use self::styledcontent::StyledContent; pub use self::traits::{Colorize, Styler}; #[macro_use] mod macros; +mod contentstyle; mod enums; -mod objectstyle; mod style; -mod styledobject; +mod styledcontent; mod traits; -/// Creates a `StyledObject`. +/// Creates a `StyledContent`. /// /// This could be used to style any type that implements `Display` with colors and text attributes. /// -/// See [`StyledObject`](struct.StyledObject.html) for more info. +/// See [`StyledContent`](struct.StyledContent.html) for more info. /// /// # Examples /// /// ```no_run /// use crossterm::{style, Color}; /// -/// let styled_object = style("Blue colored text on yellow background") +/// let styled_content = style("Blue colored text on yellow background") /// .with(Color::Blue) /// .on(Color::Yellow); /// -/// println!("{}", styled_object); +/// println!("{}", styled_content); /// ``` -pub fn style<'a, D: 'a>(val: D) -> StyledObject +pub fn style<'a, D: 'a>(val: D) -> StyledContent where D: Display + Clone, { - ObjectStyle::new().apply_to(val) + ContentStyle::new().apply(val) } impl Colorize<&'static str> for &'static str { @@ -365,20 +365,20 @@ impl Command for SetAttr { } } -/// A command to print the styled object. +/// A command to print the styled content. /// -/// See [`StyledObject`](struct.StyledObject.html) for more info. +/// See [`StyledContent`](struct.StyledContent.html) for more info. /// /// # Notes /// /// Commands must be executed/queued for execution otherwise they do nothing. -pub struct PrintStyledFont(pub StyledObject); +pub struct PrintStyledFont(pub StyledContent); impl Command for PrintStyledFont where D: Display + Clone, { - type AnsiType = StyledObject; + type AnsiType = StyledContent; fn ansi_code(&self) -> Self::AnsiType { self.0.clone() diff --git a/src/style/contentstyle.rs b/src/style/contentstyle.rs new file mode 100644 index 0000000..25fe843 --- /dev/null +++ b/src/style/contentstyle.rs @@ -0,0 +1,79 @@ +//! This module contains the `content style` that can be applied to an `styled content`. + +use std::fmt::Display; + +use super::{Attribute, Color, StyledContent}; + +/// A content style. +#[derive(Debug, Clone, Default)] +pub struct ContentStyle { + /// The foreground color. + pub fg_color: Option, + /// The background color. + pub bg_color: Option, + /// List of attributes. + pub attrs: Vec, +} + +impl ContentStyle { + /// Creates a `StyledContent` by applying the style to the given `val`. + pub fn apply(&self, val: D) -> StyledContent { + StyledContent::new(self.clone(), val) + } + + /// Creates a new `ContentStyle`. + pub fn new() -> ContentStyle { + ContentStyle::default() + } + + /// Sets the background color. + pub fn background(mut self, color: Color) -> ContentStyle { + self.bg_color = Some(color); + self + } + + /// Sets the foreground color. + pub fn foreground(mut self, color: Color) -> ContentStyle { + self.fg_color = Some(color); + self + } + + /// Adds the attribute. + /// + /// You can add more attributes by calling this method multiple times. + pub fn attribute(mut self, attr: Attribute) -> ContentStyle { + self.attrs.push(attr); + self + } +} + +#[cfg(test)] +mod tests { + use crate::{Attribute, Color, ContentStyle}; + + #[test] + fn test_set_fg_bg_add_attr() { + let content_style = ContentStyle::new() + .foreground(Color::Blue) + .background(Color::Red) + .attribute(Attribute::Reset); + + assert_eq!(content_style.fg_color, Some(Color::Blue)); + assert_eq!(content_style.bg_color, Some(Color::Red)); + assert_eq!(content_style.attrs[0], Attribute::Reset); + } + + #[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().fg_color, Some(Color::Blue)); + assert_eq!(styled_content.style().bg_color, Some(Color::Red)); + assert_eq!(styled_content.style().attrs[0], Attribute::Reset); + } +} diff --git a/src/style/enums/attribute.rs b/src/style/enums/attribute.rs index 800435f..b130d7f 100644 --- a/src/style/enums/attribute.rs +++ b/src/style/enums/attribute.rs @@ -93,7 +93,7 @@ pub enum Attribute { /// Turns off the text blinking (`SlowBlink` or `RapidBlink`). NoBlink = 25, /// Turns off the `Reverse` attribute. - NoInverse = 27, // TODO Shouldn't we rename this to `NoReverse`? Or `Reverse` to `Inverse`? + NoReverse = 27, /// Turns off the `Hidden` attribute. NoHidden = 28, /// Turns off the `CrossedOut` attribute. diff --git a/src/style/macros.rs b/src/style/macros.rs index 2138534..64ed5ed 100644 --- a/src/style/macros.rs +++ b/src/style/macros.rs @@ -1,46 +1,46 @@ macro_rules! def_attr { ($name:ident => $attr:path) => { - fn $name(self) -> StyledObject { - self.attr($attr) + fn $name(self) -> StyledContent { + self.attribute($attr) } }; } macro_rules! def_color { ($side:ident: $name:ident => $color:path) => { - fn $name(self) -> StyledObject { - StyledObject { - object_style: ObjectStyle { + fn $name(self) -> StyledContent { + StyledContent::new( + ContentStyle { $side: Some($color), - ..self.object_style + ..self.style }, - ..self - } + self.content + ) } }; } macro_rules! def_str_color { ($side:ident: $name:ident => $color:path) => { - fn $name(self) -> StyledObject< &'static str> { - StyledObject { - object_style: ObjectStyle { + fn $name(self) -> StyledContent< &'static str> { + StyledContent::new( + ContentStyle { $side: Some($color), ..Default::default() }, - content: self - } + self + ) } }; } macro_rules! def_str_attr { ($name:ident => $color:path) => { - fn $name(self) -> StyledObject<&'static str> { - StyledObject { - object_style: Default::default(), - content: self, - } + fn $name(self) -> StyledContent<&'static str> { + StyledContent::new( + Default::default(), + self + ) } } } diff --git a/src/style/objectstyle.rs b/src/style/objectstyle.rs deleted file mode 100644 index ea6c501..0000000 --- a/src/style/objectstyle.rs +++ /dev/null @@ -1,77 +0,0 @@ -//! This module contains the `object style` that can be applied to an `styled object`. - -use std::fmt::Display; - -use super::{Attribute, Color, StyledObject}; - -/// An object style. -#[derive(Debug, Clone, Default)] -pub struct ObjectStyle { - /// The foreground color. - pub fg_color: Option, - /// The background color. - pub bg_color: Option, - /// List of attributes. - pub attrs: Vec, -} - -impl ObjectStyle { - /// Creates a `StyledObject` by applying the style to the given `val`. - pub fn apply_to(&self, val: D) -> StyledObject { - StyledObject { - object_style: self.clone(), - content: val, - } - } - - /// Creates a new `ObjectStyle`. - pub fn new() -> ObjectStyle { - ObjectStyle::default() - } - - /// Sets the background color. - pub fn bg(mut self, color: Color) -> ObjectStyle { - self.bg_color = Some(color); - self - } - - /// Sets the foreground color. - pub fn fg(mut self, color: Color) -> ObjectStyle { - self.fg_color = Some(color); - self - } - - /// Adds the attribute. - /// - /// You can add more attributes by calling this method multiple times. - pub fn add_attr(&mut self, attr: Attribute) { - self.attrs.push(attr); - } -} - -#[cfg(test)] -mod tests { - use crate::{Attribute, Color, ObjectStyle}; - - #[test] - fn test_set_fg_bg_add_attr() { - let mut object_style = ObjectStyle::new().fg(Color::Blue).bg(Color::Red); - object_style.add_attr(Attribute::Reset); - - assert_eq!(object_style.fg_color, Some(Color::Blue)); - assert_eq!(object_style.bg_color, Some(Color::Red)); - assert_eq!(object_style.attrs[0], Attribute::Reset); - } - - #[test] - fn test_apply_object_style_to_text() { - let mut object_style = ObjectStyle::new().fg(Color::Blue).bg(Color::Red); - object_style.add_attr(Attribute::Reset); - - let styled_object = object_style.apply_to("test"); - - assert_eq!(styled_object.object_style.fg_color, Some(Color::Blue)); - assert_eq!(styled_object.object_style.bg_color, Some(Color::Red)); - assert_eq!(styled_object.object_style.attrs[0], Attribute::Reset); - } -} diff --git a/src/style/styledobject.rs b/src/style/styledcontent.rs similarity index 62% rename from src/style/styledobject.rs rename to src/style/styledcontent.rs index 685ca81..55ec0df 100644 --- a/src/style/styledobject.rs +++ b/src/style/styledcontent.rs @@ -1,13 +1,13 @@ -//! This module contains the logic to style an object that contains some 'content' which can be styled. +//! This module contains the logic to style some content. use std::fmt::{self, Display, Formatter}; use std::result; use crate::queue; -use super::{Attribute, Color, Colorize, ObjectStyle, ResetColor, SetAttr, SetBg, SetFg, Styler}; +use super::{Attribute, Color, Colorize, ContentStyle, ResetColor, SetAttr, SetBg, SetFg, Styler}; -/// A styled object. +/// A styled content. /// /// # Examples /// @@ -17,54 +17,69 @@ use super::{Attribute, Color, Colorize, ObjectStyle, ResetColor, SetAttr, SetBg, /// let styled = style("Hello there") /// .with(Color::Yellow) /// .on(Color::Blue) -/// .attr(Attribute::Bold); +/// .attribute(Attribute::Bold); /// /// println!("{}", styled); /// ``` #[derive(Clone)] -pub struct StyledObject { - /// The object style (colors, content attributes). - pub object_style: ObjectStyle, - /// An object to apply the style on. - pub content: D, +pub struct StyledContent { + /// The style (colors, content attributes). + style: ContentStyle, + /// A content to apply the style on. + content: D, } -impl<'a, D: Display + 'a + Clone> StyledObject { +impl<'a, D: Display + 'a + Clone> StyledContent { + /// Creates a new `StyledContent`. + pub fn new(style: ContentStyle, content: D) -> StyledContent { + StyledContent { style, content } + } + /// Sets the foreground color. - pub fn with(mut self, foreground_color: Color) -> StyledObject { - self.object_style = self.object_style.fg(foreground_color); + pub fn with(mut self, foreground_color: Color) -> StyledContent { + self.style = self.style.foreground(foreground_color); self } /// Sets the background color. - pub fn on(mut self, background_color: Color) -> StyledObject { - self.object_style = self.object_style.bg(background_color); + pub fn on(mut 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. - pub fn attr(mut self, attr: Attribute) -> StyledObject { - self.object_style.add_attr(attr); + pub fn attribute(mut self, attr: Attribute) -> StyledContent { + self.style = self.style.attribute(attr); self } + + /// Returns the content. + pub fn content(&self) -> &D { + &self.content + } + + /// Returns the style. + pub fn style(&self) -> &ContentStyle { + &self.style + } } -impl Display for StyledObject { +impl Display for StyledContent { fn fmt(&self, f: &mut Formatter<'_>) -> result::Result<(), fmt::Error> { let mut reset = false; - if let Some(bg) = self.object_style.bg_color { + if let Some(bg) = self.style.bg_color { queue!(f, SetBg(bg)).map_err(|_| fmt::Error)?; reset = true; } - if let Some(fg) = self.object_style.fg_color { + if let Some(fg) = self.style.fg_color { queue!(f, SetFg(fg)).map_err(|_| fmt::Error)?; reset = true; } - for attr in self.object_style.attrs.iter() { + for attr in self.style.attrs.iter() { queue!(f, SetAttr(*attr)).map_err(|_| fmt::Error)?; reset = true; } @@ -79,7 +94,7 @@ impl Display for StyledObject { } } -impl Colorize for StyledObject { +impl Colorize for StyledContent { // foreground colors def_color!(fg_color: black => Color::Black); def_color!(fg_color: dark_grey => Color::DarkGrey); @@ -117,7 +132,7 @@ impl Colorize for StyledObject { def_color!(bg_color: on_grey => Color::Grey); } -impl Styler for StyledObject { +impl Styler for StyledContent { def_attr!(reset => Attribute::Reset); def_attr!(bold => Attribute::Bold); def_attr!(underlined => Attribute::Underlined); @@ -133,24 +148,26 @@ impl Styler for StyledObject { #[cfg(test)] mod tests { - use super::{Attribute, Color, ObjectStyle}; + use super::{Attribute, Color, ContentStyle}; #[test] fn test_set_fg_bg_add_attr() { - let mut object_style = ObjectStyle::new().fg(Color::Blue).bg(Color::Red); - object_style.add_attr(Attribute::Reset); + let style = ContentStyle::new() + .foreground(Color::Blue) + .background(Color::Red) + .attribute(Attribute::Reset); - let mut styled_object = object_style.apply_to("test"); + let mut styled_content = style.apply("test"); - styled_object = styled_object + styled_content = styled_content .with(Color::Green) .on(Color::Magenta) - .attr(Attribute::NoItalic); + .attribute(Attribute::NoItalic); - assert_eq!(styled_object.object_style.fg_color, Some(Color::Green)); - assert_eq!(styled_object.object_style.bg_color, Some(Color::Magenta)); - assert_eq!(styled_object.object_style.attrs.len(), 2); - assert_eq!(styled_object.object_style.attrs[0], Attribute::Reset); - assert_eq!(styled_object.object_style.attrs[1], Attribute::NoItalic); + assert_eq!(styled_content.style.fg_color, Some(Color::Green)); + assert_eq!(styled_content.style.bg_color, Some(Color::Magenta)); + assert_eq!(styled_content.style.attrs.len(), 2); + assert_eq!(styled_content.style.attrs[0], Attribute::Reset); + assert_eq!(styled_content.style.attrs[1], Attribute::NoItalic); } } diff --git a/src/style/traits.rs b/src/style/traits.rs index 08658a8..ad408d5 100644 --- a/src/style/traits.rs +++ b/src/style/traits.rs @@ -1,6 +1,6 @@ use std::fmt::Display; -use super::StyledObject; +use super::StyledContent; /// Provides a set of methods to set the colors. /// @@ -18,39 +18,39 @@ use super::StyledObject; /// println!("{}", styled_text); /// ``` pub trait Colorize { - fn black(self) -> StyledObject; - fn dark_grey(self) -> StyledObject; - fn red(self) -> StyledObject; - fn dark_red(self) -> StyledObject; - fn green(self) -> StyledObject; - fn dark_green(self) -> StyledObject; - fn yellow(self) -> StyledObject; - fn dark_yellow(self) -> StyledObject; - fn blue(self) -> StyledObject; - fn dark_blue(self) -> StyledObject; - fn magenta(self) -> StyledObject; - fn dark_magenta(self) -> StyledObject; - fn cyan(self) -> StyledObject; - fn dark_cyan(self) -> StyledObject; - fn white(self) -> StyledObject; - fn grey(self) -> StyledObject; + 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) -> StyledObject; - fn on_dark_grey(self) -> StyledObject; - fn on_red(self) -> StyledObject; - fn on_dark_red(self) -> StyledObject; - fn on_green(self) -> StyledObject; - fn on_dark_green(self) -> StyledObject; - fn on_yellow(self) -> StyledObject; - fn on_dark_yellow(self) -> StyledObject; - fn on_blue(self) -> StyledObject; - fn on_dark_blue(self) -> StyledObject; - fn on_magenta(self) -> StyledObject; - fn on_dark_magenta(self) -> StyledObject; - fn on_cyan(self) -> StyledObject; - fn on_dark_cyan(self) -> StyledObject; - fn on_white(self) -> StyledObject; - fn on_grey(self) -> StyledObject; + 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. @@ -67,15 +67,15 @@ pub trait Colorize { /// println!("{}", "Negative text".negative()); /// ``` pub trait Styler { - fn reset(self) -> StyledObject; - fn bold(self) -> StyledObject; - fn underlined(self) -> StyledObject; - fn reverse(self) -> StyledObject; - fn dim(self) -> StyledObject; - fn italic(self) -> StyledObject; - fn negative(self) -> StyledObject; - fn slow_blink(self) -> StyledObject; - fn rapid_blink(self) -> StyledObject; - fn hidden(self) -> StyledObject; - fn crossed_out(self) -> StyledObject; + 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; }