Refactor the Style Module (#291)

This commit is contained in:
ebroto 2019-10-27 21:07:09 +01:00 committed by Timon
parent 0479d68f50
commit ea7130a419
11 changed files with 217 additions and 194 deletions

View File

@ -14,7 +14,12 @@
- Rename `ResetPos` to `ResetPosition` - Rename `ResetPos` to `ResetPosition`
- Rename `SavePos` to `SavePosition` - Rename `SavePos` to `SavePosition`
- Remove re-export cursor module types at root level, are now accessible from `crossterm::cursor` - 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 # Version 0.12.1
- All the `crossterm_` crates code was moved to the `crossterm` crate - All the `crossterm_` crates code was moved to the `crossterm` crate

View File

@ -20,7 +20,6 @@ see [Tested Terminals](#tested-terminals) for more info).
* [Tested Terminals](#tested-terminals) * [Tested Terminals](#tested-terminals)
* [Getting Started](#getting-started) * [Getting Started](#getting-started)
* [Feature Flags](#feature-flags) * [Feature Flags](#feature-flags)
* [`crossterm` vs `crossterm_*` crates](#crossterm-vs-crossterm_-crates)
* [Other Resources](#other-resources) * [Other Resources](#other-resources)
* [Used By](#used-by) * [Used By](#used-by)
* [Contributing](#contributing) * [Contributing](#contributing)

View File

@ -28,12 +28,12 @@ impl Crossterm {
crate::style::TerminalColor::new() crate::style::TerminalColor::new()
} }
/// Creates a new `StyledObject`. /// Creates a new `StyledContent`.
#[cfg(feature = "style")] #[cfg(feature = "style")]
pub fn style<D>(&self, val: D) -> crate::style::StyledObject<D> pub fn style<D>(&self, val: D) -> crate::style::StyledContent<D>
where where
D: Display + Clone, D: Display + Clone,
{ {
crate::style::ObjectStyle::new().apply_to(val) crate::style::ContentStyle::new().apply(val)
} }
} }

View File

@ -177,8 +177,8 @@ pub use screen::{
}; };
#[cfg(feature = "style")] #[cfg(feature = "style")]
pub use style::{ pub use style::{
color, style, Attribute, Color, Colored, Colorize, ObjectStyle, PrintStyledFont, ResetColor, color, style, Attribute, Color, Colored, Colorize, ContentStyle, PrintStyledFont, ResetColor,
SetAttr, SetBg, SetFg, StyledObject, Styler, TerminalColor, SetAttr, SetBg, SetFg, StyledContent, Styler, TerminalColor,
}; };
#[cfg(feature = "terminal")] #[cfg(feature = "terminal")]
pub use terminal::{terminal, Clear, ClearType, ScrollDown, ScrollUp, SetSize, Terminal}; pub use terminal::{terminal, Clear, ClearType, ScrollDown, ScrollUp, SetSize, Terminal};

View File

@ -115,41 +115,41 @@ use crate::impl_display;
use crate::utils::supports_ansi; use crate::utils::supports_ansi;
use crate::utils::{Command, Result}; use crate::utils::{Command, Result};
pub use self::contentstyle::ContentStyle;
pub use self::enums::{Attribute, Color, Colored}; pub use self::enums::{Attribute, Color, Colored};
pub use self::objectstyle::ObjectStyle; pub use self::styledcontent::StyledContent;
pub use self::styledobject::StyledObject;
pub use self::traits::{Colorize, Styler}; pub use self::traits::{Colorize, Styler};
#[macro_use] #[macro_use]
mod macros; mod macros;
mod contentstyle;
mod enums; mod enums;
mod objectstyle;
mod style; mod style;
mod styledobject; mod styledcontent;
mod traits; mod traits;
/// Creates a `StyledObject`. /// Creates a `StyledContent`.
/// ///
/// This could be used to style any type that implements `Display` with colors and text attributes. /// 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 /// # Examples
/// ///
/// ```no_run /// ```no_run
/// use crossterm::{style, Color}; /// 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) /// .with(Color::Blue)
/// .on(Color::Yellow); /// .on(Color::Yellow);
/// ///
/// println!("{}", styled_object); /// println!("{}", styled_content);
/// ``` /// ```
pub fn style<'a, D: 'a>(val: D) -> StyledObject<D> pub fn style<'a, D: 'a>(val: D) -> StyledContent<D>
where where
D: Display + Clone, D: Display + Clone,
{ {
ObjectStyle::new().apply_to(val) ContentStyle::new().apply(val)
} }
impl Colorize<&'static str> for &'static str { 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 /// # Notes
/// ///
/// Commands must be executed/queued for execution otherwise they do nothing. /// Commands must be executed/queued for execution otherwise they do nothing.
pub struct PrintStyledFont<D: Display + Clone>(pub StyledObject<D>); pub struct PrintStyledFont<D: Display + Clone>(pub StyledContent<D>);
impl<D> Command for PrintStyledFont<D> impl<D> Command for PrintStyledFont<D>
where where
D: Display + Clone, D: Display + Clone,
{ {
type AnsiType = StyledObject<D>; type AnsiType = StyledContent<D>;
fn ansi_code(&self) -> Self::AnsiType { fn ansi_code(&self) -> Self::AnsiType {
self.0.clone() self.0.clone()

79
src/style/contentstyle.rs Normal file
View File

@ -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<Color>,
/// The background color.
pub bg_color: Option<Color>,
/// List of attributes.
pub attrs: Vec<Attribute>,
}
impl ContentStyle {
/// Creates a `StyledContent` by applying the style to the given `val`.
pub fn apply<D: Display + Clone>(&self, val: D) -> StyledContent<D> {
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);
}
}

View File

@ -93,7 +93,7 @@ pub enum Attribute {
/// Turns off the text blinking (`SlowBlink` or `RapidBlink`). /// Turns off the text blinking (`SlowBlink` or `RapidBlink`).
NoBlink = 25, NoBlink = 25,
/// Turns off the `Reverse` attribute. /// 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. /// Turns off the `Hidden` attribute.
NoHidden = 28, NoHidden = 28,
/// Turns off the `CrossedOut` attribute. /// Turns off the `CrossedOut` attribute.

View File

@ -1,46 +1,46 @@
macro_rules! def_attr { macro_rules! def_attr {
($name:ident => $attr:path) => { ($name:ident => $attr:path) => {
fn $name(self) -> StyledObject<D> { fn $name(self) -> StyledContent<D> {
self.attr($attr) self.attribute($attr)
} }
}; };
} }
macro_rules! def_color { macro_rules! def_color {
($side:ident: $name:ident => $color:path) => { ($side:ident: $name:ident => $color:path) => {
fn $name(self) -> StyledObject<D> { fn $name(self) -> StyledContent<D> {
StyledObject { StyledContent::new(
object_style: ObjectStyle { ContentStyle {
$side: Some($color), $side: Some($color),
..self.object_style ..self.style
}, },
..self self.content
} )
} }
}; };
} }
macro_rules! def_str_color { macro_rules! def_str_color {
($side:ident: $name:ident => $color:path) => { ($side:ident: $name:ident => $color:path) => {
fn $name(self) -> StyledObject< &'static str> { fn $name(self) -> StyledContent< &'static str> {
StyledObject { StyledContent::new(
object_style: ObjectStyle { ContentStyle {
$side: Some($color), $side: Some($color),
..Default::default() ..Default::default()
}, },
content: self self
} )
} }
}; };
} }
macro_rules! def_str_attr { macro_rules! def_str_attr {
($name:ident => $color:path) => { ($name:ident => $color:path) => {
fn $name(self) -> StyledObject<&'static str> { fn $name(self) -> StyledContent<&'static str> {
StyledObject { StyledContent::new(
object_style: Default::default(), Default::default(),
content: self, self
} )
} }
} }
} }

View File

@ -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<Color>,
/// The background color.
pub bg_color: Option<Color>,
/// List of attributes.
pub attrs: Vec<Attribute>,
}
impl ObjectStyle {
/// Creates a `StyledObject` by applying the style to the given `val`.
pub fn apply_to<D: Display + Clone>(&self, val: D) -> StyledObject<D> {
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);
}
}

View File

@ -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::fmt::{self, Display, Formatter};
use std::result; use std::result;
use crate::queue; 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 /// # Examples
/// ///
@ -17,54 +17,69 @@ use super::{Attribute, Color, Colorize, ObjectStyle, ResetColor, SetAttr, SetBg,
/// let styled = style("Hello there") /// let styled = style("Hello there")
/// .with(Color::Yellow) /// .with(Color::Yellow)
/// .on(Color::Blue) /// .on(Color::Blue)
/// .attr(Attribute::Bold); /// .attribute(Attribute::Bold);
/// ///
/// println!("{}", styled); /// println!("{}", styled);
/// ``` /// ```
#[derive(Clone)] #[derive(Clone)]
pub struct StyledObject<D: Display + Clone> { pub struct StyledContent<D: Display + Clone> {
/// The object style (colors, content attributes). /// The style (colors, content attributes).
pub object_style: ObjectStyle, style: ContentStyle,
/// An object to apply the style on. /// A content to apply the style on.
pub content: D, content: D,
} }
impl<'a, D: Display + 'a + Clone> StyledObject<D> { impl<'a, D: Display + 'a + Clone> StyledContent<D> {
/// Creates a new `StyledContent`.
pub fn new(style: ContentStyle, content: D) -> StyledContent<D> {
StyledContent { style, content }
}
/// Sets the foreground color. /// Sets the foreground color.
pub fn with(mut self, foreground_color: Color) -> StyledObject<D> { pub fn with(mut self, foreground_color: Color) -> StyledContent<D> {
self.object_style = self.object_style.fg(foreground_color); self.style = self.style.foreground(foreground_color);
self self
} }
/// Sets the background color. /// Sets the background color.
pub fn on(mut self, background_color: Color) -> StyledObject<D> { pub fn on(mut self, background_color: Color) -> StyledContent<D> {
self.object_style = self.object_style.bg(background_color); self.style = self.style.background(background_color);
self self
} }
/// Adds the attribute. /// Adds the attribute.
/// ///
/// You can add more attributes by calling this method multiple times. /// You can add more attributes by calling this method multiple times.
pub fn attr(mut self, attr: Attribute) -> StyledObject<D> { pub fn attribute(mut self, attr: Attribute) -> StyledContent<D> {
self.object_style.add_attr(attr); self.style = self.style.attribute(attr);
self self
} }
/// Returns the content.
pub fn content(&self) -> &D {
&self.content
}
/// Returns the style.
pub fn style(&self) -> &ContentStyle {
&self.style
}
} }
impl<D: Display + Clone> Display for StyledObject<D> { impl<D: Display + Clone> Display for StyledContent<D> {
fn fmt(&self, f: &mut Formatter<'_>) -> result::Result<(), fmt::Error> { fn fmt(&self, f: &mut Formatter<'_>) -> result::Result<(), fmt::Error> {
let mut reset = false; 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)?; queue!(f, SetBg(bg)).map_err(|_| fmt::Error)?;
reset = true; 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)?; queue!(f, SetFg(fg)).map_err(|_| fmt::Error)?;
reset = true; 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)?; queue!(f, SetAttr(*attr)).map_err(|_| fmt::Error)?;
reset = true; reset = true;
} }
@ -79,7 +94,7 @@ impl<D: Display + Clone> Display for StyledObject<D> {
} }
} }
impl<D: Display + Clone> Colorize<D> for StyledObject<D> { impl<D: Display + Clone> Colorize<D> for StyledContent<D> {
// foreground colors // foreground colors
def_color!(fg_color: black => Color::Black); def_color!(fg_color: black => Color::Black);
def_color!(fg_color: dark_grey => Color::DarkGrey); def_color!(fg_color: dark_grey => Color::DarkGrey);
@ -117,7 +132,7 @@ impl<D: Display + Clone> Colorize<D> for StyledObject<D> {
def_color!(bg_color: on_grey => Color::Grey); def_color!(bg_color: on_grey => Color::Grey);
} }
impl<D: Display + Clone> Styler<D> for StyledObject<D> { impl<D: Display + Clone> Styler<D> for StyledContent<D> {
def_attr!(reset => Attribute::Reset); def_attr!(reset => Attribute::Reset);
def_attr!(bold => Attribute::Bold); def_attr!(bold => Attribute::Bold);
def_attr!(underlined => Attribute::Underlined); def_attr!(underlined => Attribute::Underlined);
@ -133,24 +148,26 @@ impl<D: Display + Clone> Styler<D> for StyledObject<D> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::{Attribute, Color, ObjectStyle}; use super::{Attribute, Color, ContentStyle};
#[test] #[test]
fn test_set_fg_bg_add_attr() { fn test_set_fg_bg_add_attr() {
let mut object_style = ObjectStyle::new().fg(Color::Blue).bg(Color::Red); let style = ContentStyle::new()
object_style.add_attr(Attribute::Reset); .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) .with(Color::Green)
.on(Color::Magenta) .on(Color::Magenta)
.attr(Attribute::NoItalic); .attribute(Attribute::NoItalic);
assert_eq!(styled_object.object_style.fg_color, Some(Color::Green)); assert_eq!(styled_content.style.fg_color, Some(Color::Green));
assert_eq!(styled_object.object_style.bg_color, Some(Color::Magenta)); assert_eq!(styled_content.style.bg_color, Some(Color::Magenta));
assert_eq!(styled_object.object_style.attrs.len(), 2); assert_eq!(styled_content.style.attrs.len(), 2);
assert_eq!(styled_object.object_style.attrs[0], Attribute::Reset); assert_eq!(styled_content.style.attrs[0], Attribute::Reset);
assert_eq!(styled_object.object_style.attrs[1], Attribute::NoItalic); assert_eq!(styled_content.style.attrs[1], Attribute::NoItalic);
} }
} }

View File

@ -1,6 +1,6 @@
use std::fmt::Display; use std::fmt::Display;
use super::StyledObject; use super::StyledContent;
/// Provides a set of methods to set the colors. /// Provides a set of methods to set the colors.
/// ///
@ -18,39 +18,39 @@ use super::StyledObject;
/// println!("{}", styled_text); /// println!("{}", styled_text);
/// ``` /// ```
pub trait Colorize<D: Display + Clone> { pub trait Colorize<D: Display + Clone> {
fn black(self) -> StyledObject<D>; fn black(self) -> StyledContent<D>;
fn dark_grey(self) -> StyledObject<D>; fn dark_grey(self) -> StyledContent<D>;
fn red(self) -> StyledObject<D>; fn red(self) -> StyledContent<D>;
fn dark_red(self) -> StyledObject<D>; fn dark_red(self) -> StyledContent<D>;
fn green(self) -> StyledObject<D>; fn green(self) -> StyledContent<D>;
fn dark_green(self) -> StyledObject<D>; fn dark_green(self) -> StyledContent<D>;
fn yellow(self) -> StyledObject<D>; fn yellow(self) -> StyledContent<D>;
fn dark_yellow(self) -> StyledObject<D>; fn dark_yellow(self) -> StyledContent<D>;
fn blue(self) -> StyledObject<D>; fn blue(self) -> StyledContent<D>;
fn dark_blue(self) -> StyledObject<D>; fn dark_blue(self) -> StyledContent<D>;
fn magenta(self) -> StyledObject<D>; fn magenta(self) -> StyledContent<D>;
fn dark_magenta(self) -> StyledObject<D>; fn dark_magenta(self) -> StyledContent<D>;
fn cyan(self) -> StyledObject<D>; fn cyan(self) -> StyledContent<D>;
fn dark_cyan(self) -> StyledObject<D>; fn dark_cyan(self) -> StyledContent<D>;
fn white(self) -> StyledObject<D>; fn white(self) -> StyledContent<D>;
fn grey(self) -> StyledObject<D>; fn grey(self) -> StyledContent<D>;
fn on_black(self) -> StyledObject<D>; fn on_black(self) -> StyledContent<D>;
fn on_dark_grey(self) -> StyledObject<D>; fn on_dark_grey(self) -> StyledContent<D>;
fn on_red(self) -> StyledObject<D>; fn on_red(self) -> StyledContent<D>;
fn on_dark_red(self) -> StyledObject<D>; fn on_dark_red(self) -> StyledContent<D>;
fn on_green(self) -> StyledObject<D>; fn on_green(self) -> StyledContent<D>;
fn on_dark_green(self) -> StyledObject<D>; fn on_dark_green(self) -> StyledContent<D>;
fn on_yellow(self) -> StyledObject<D>; fn on_yellow(self) -> StyledContent<D>;
fn on_dark_yellow(self) -> StyledObject<D>; fn on_dark_yellow(self) -> StyledContent<D>;
fn on_blue(self) -> StyledObject<D>; fn on_blue(self) -> StyledContent<D>;
fn on_dark_blue(self) -> StyledObject<D>; fn on_dark_blue(self) -> StyledContent<D>;
fn on_magenta(self) -> StyledObject<D>; fn on_magenta(self) -> StyledContent<D>;
fn on_dark_magenta(self) -> StyledObject<D>; fn on_dark_magenta(self) -> StyledContent<D>;
fn on_cyan(self) -> StyledObject<D>; fn on_cyan(self) -> StyledContent<D>;
fn on_dark_cyan(self) -> StyledObject<D>; fn on_dark_cyan(self) -> StyledContent<D>;
fn on_white(self) -> StyledObject<D>; fn on_white(self) -> StyledContent<D>;
fn on_grey(self) -> StyledObject<D>; fn on_grey(self) -> StyledContent<D>;
} }
/// Provides a set of methods to set the text attributes. /// Provides a set of methods to set the text attributes.
@ -67,15 +67,15 @@ pub trait Colorize<D: Display + Clone> {
/// println!("{}", "Negative text".negative()); /// println!("{}", "Negative text".negative());
/// ``` /// ```
pub trait Styler<D: Display + Clone> { pub trait Styler<D: Display + Clone> {
fn reset(self) -> StyledObject<D>; fn reset(self) -> StyledContent<D>;
fn bold(self) -> StyledObject<D>; fn bold(self) -> StyledContent<D>;
fn underlined(self) -> StyledObject<D>; fn underlined(self) -> StyledContent<D>;
fn reverse(self) -> StyledObject<D>; fn reverse(self) -> StyledContent<D>;
fn dim(self) -> StyledObject<D>; fn dim(self) -> StyledContent<D>;
fn italic(self) -> StyledObject<D>; fn italic(self) -> StyledContent<D>;
fn negative(self) -> StyledObject<D>; fn negative(self) -> StyledContent<D>;
fn slow_blink(self) -> StyledObject<D>; fn slow_blink(self) -> StyledContent<D>;
fn rapid_blink(self) -> StyledObject<D>; fn rapid_blink(self) -> StyledContent<D>;
fn hidden(self) -> StyledObject<D>; fn hidden(self) -> StyledContent<D>;
fn crossed_out(self) -> StyledObject<D>; fn crossed_out(self) -> StyledContent<D>;
} }