Add macros for Colorize
and Styler
impls, add an impl for String
(#420)
This commit is contained in:
parent
d4fc75cca1
commit
43fbdfce0d
108
src/style.rs
108
src/style.rs
@ -160,109 +160,13 @@ where
|
|||||||
ContentStyle::new().apply(val)
|
ContentStyle::new().apply(val)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Colorize<&'static str> for &'static str {
|
impl_colorize!(String);
|
||||||
// foreground colors
|
impl_colorize!(&'static str);
|
||||||
def_str_color!(foreground_color: black => Color::Black);
|
impl_colorize!(char);
|
||||||
def_str_color!(foreground_color: dark_grey => Color::DarkGrey);
|
|
||||||
def_str_color!(foreground_color: red => Color::Red);
|
|
||||||
def_str_color!(foreground_color: dark_red => Color::DarkRed);
|
|
||||||
def_str_color!(foreground_color: green => Color::Green);
|
|
||||||
def_str_color!(foreground_color: dark_green => Color::DarkGreen);
|
|
||||||
def_str_color!(foreground_color: yellow => Color::Yellow);
|
|
||||||
def_str_color!(foreground_color: dark_yellow => Color::DarkYellow);
|
|
||||||
def_str_color!(foreground_color: blue => Color::Blue);
|
|
||||||
def_str_color!(foreground_color: dark_blue => Color::DarkBlue);
|
|
||||||
def_str_color!(foreground_color: magenta => Color::Magenta);
|
|
||||||
def_str_color!(foreground_color: dark_magenta => Color::DarkMagenta);
|
|
||||||
def_str_color!(foreground_color: cyan => Color::Cyan);
|
|
||||||
def_str_color!(foreground_color: dark_cyan => Color::DarkCyan);
|
|
||||||
def_str_color!(foreground_color: white => Color::White);
|
|
||||||
def_str_color!(foreground_color: grey => Color::Grey);
|
|
||||||
|
|
||||||
// background colors
|
impl_styler!(String);
|
||||||
def_str_color!(background_color: on_black => Color::Black);
|
impl_styler!(&'static str);
|
||||||
def_str_color!(background_color: on_dark_grey => Color::DarkGrey);
|
impl_styler!(char);
|
||||||
def_str_color!(background_color: on_red => Color::Red);
|
|
||||||
def_str_color!(background_color: on_dark_red => Color::DarkRed);
|
|
||||||
def_str_color!(background_color: on_green => Color::Green);
|
|
||||||
def_str_color!(background_color: on_dark_green => Color::DarkGreen);
|
|
||||||
def_str_color!(background_color: on_yellow => Color::Yellow);
|
|
||||||
def_str_color!(background_color: on_dark_yellow => Color::DarkYellow);
|
|
||||||
def_str_color!(background_color: on_blue => Color::Blue);
|
|
||||||
def_str_color!(background_color: on_dark_blue => Color::DarkBlue);
|
|
||||||
def_str_color!(background_color: on_magenta => Color::Magenta);
|
|
||||||
def_str_color!(background_color: on_dark_magenta => Color::DarkMagenta);
|
|
||||||
def_str_color!(background_color: on_cyan => Color::Cyan);
|
|
||||||
def_str_color!(background_color: on_dark_cyan => Color::DarkCyan);
|
|
||||||
def_str_color!(background_color: on_white => Color::White);
|
|
||||||
def_str_color!(background_color: on_grey => Color::Grey);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Colorize<char> for char {
|
|
||||||
// foreground colors
|
|
||||||
def_char_color!(foreground_color: black => Color::Black);
|
|
||||||
def_char_color!(foreground_color: dark_grey => Color::DarkGrey);
|
|
||||||
def_char_color!(foreground_color: red => Color::Red);
|
|
||||||
def_char_color!(foreground_color: dark_red => Color::DarkRed);
|
|
||||||
def_char_color!(foreground_color: green => Color::Green);
|
|
||||||
def_char_color!(foreground_color: dark_green => Color::DarkGreen);
|
|
||||||
def_char_color!(foreground_color: yellow => Color::Yellow);
|
|
||||||
def_char_color!(foreground_color: dark_yellow => Color::DarkYellow);
|
|
||||||
def_char_color!(foreground_color: blue => Color::Blue);
|
|
||||||
def_char_color!(foreground_color: dark_blue => Color::DarkBlue);
|
|
||||||
def_char_color!(foreground_color: magenta => Color::Magenta);
|
|
||||||
def_char_color!(foreground_color: dark_magenta => Color::DarkMagenta);
|
|
||||||
def_char_color!(foreground_color: cyan => Color::Cyan);
|
|
||||||
def_char_color!(foreground_color: dark_cyan => Color::DarkCyan);
|
|
||||||
def_char_color!(foreground_color: white => Color::White);
|
|
||||||
def_char_color!(foreground_color: grey => Color::Grey);
|
|
||||||
|
|
||||||
// background colors
|
|
||||||
def_char_color!(background_color: on_black => Color::Black);
|
|
||||||
def_char_color!(background_color: on_dark_grey => Color::DarkGrey);
|
|
||||||
def_char_color!(background_color: on_red => Color::Red);
|
|
||||||
def_char_color!(background_color: on_dark_red => Color::DarkRed);
|
|
||||||
def_char_color!(background_color: on_green => Color::Green);
|
|
||||||
def_char_color!(background_color: on_dark_green => Color::DarkGreen);
|
|
||||||
def_char_color!(background_color: on_yellow => Color::Yellow);
|
|
||||||
def_char_color!(background_color: on_dark_yellow => Color::DarkYellow);
|
|
||||||
def_char_color!(background_color: on_blue => Color::Blue);
|
|
||||||
def_char_color!(background_color: on_dark_blue => Color::DarkBlue);
|
|
||||||
def_char_color!(background_color: on_magenta => Color::Magenta);
|
|
||||||
def_char_color!(background_color: on_dark_magenta => Color::DarkMagenta);
|
|
||||||
def_char_color!(background_color: on_cyan => Color::Cyan);
|
|
||||||
def_char_color!(background_color: on_dark_cyan => Color::DarkCyan);
|
|
||||||
def_char_color!(background_color: on_white => Color::White);
|
|
||||||
def_char_color!(background_color: on_grey => Color::Grey);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Styler<&'static str> for &'static str {
|
|
||||||
def_str_attr!(reset => Attribute::Reset);
|
|
||||||
def_str_attr!(bold => Attribute::Bold);
|
|
||||||
def_str_attr!(underlined => Attribute::Underlined);
|
|
||||||
def_str_attr!(reverse => Attribute::Reverse);
|
|
||||||
def_str_attr!(dim => Attribute::Dim);
|
|
||||||
def_str_attr!(italic => Attribute::Italic);
|
|
||||||
def_str_attr!(negative => Attribute::Reverse);
|
|
||||||
def_str_attr!(slow_blink => Attribute::SlowBlink);
|
|
||||||
def_str_attr!(rapid_blink => Attribute::RapidBlink);
|
|
||||||
def_str_attr!(hidden => Attribute::Hidden);
|
|
||||||
def_str_attr!(crossed_out => Attribute::CrossedOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Styler<char> for char {
|
|
||||||
def_char_attr!(reset => Attribute::Reset);
|
|
||||||
def_char_attr!(bold => Attribute::Bold);
|
|
||||||
def_char_attr!(underlined => Attribute::Underlined);
|
|
||||||
def_char_attr!(reverse => Attribute::Reverse);
|
|
||||||
def_char_attr!(dim => Attribute::Dim);
|
|
||||||
def_char_attr!(italic => Attribute::Italic);
|
|
||||||
def_char_attr!(negative => Attribute::Reverse);
|
|
||||||
def_char_attr!(slow_blink => Attribute::SlowBlink);
|
|
||||||
def_char_attr!(rapid_blink => Attribute::RapidBlink);
|
|
||||||
def_char_attr!(hidden => Attribute::Hidden);
|
|
||||||
def_char_attr!(crossed_out => Attribute::CrossedOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns available color count.
|
/// Returns available color count.
|
||||||
///
|
///
|
||||||
|
@ -1,13 +1,123 @@
|
|||||||
macro_rules! def_attr {
|
//! Defines the macros for repetitive styling implementations
|
||||||
($name:ident => $attr:path) => {
|
|
||||||
|
// 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<D>'.
|
||||||
|
//
|
||||||
|
// 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<D>`. 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<D>'.
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// `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 collase 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<D>'
|
||||||
|
//
|
||||||
|
// 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<D> {
|
fn $name(self) -> StyledContent<D> {
|
||||||
self.attribute($attr)
|
self.attribute($attr)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! def_color {
|
// Produces the set of methods inside the implementation, but not the outer block itself
|
||||||
($side:ident: $name:ident => $color:path) => {
|
//
|
||||||
|
// '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<D> {
|
fn $name(self) -> StyledContent<D> {
|
||||||
StyledContent::new(
|
StyledContent::new(
|
||||||
ContentStyle {
|
ContentStyle {
|
||||||
@ -20,58 +130,50 @@ macro_rules! def_color {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! def_str_color {
|
macro_rules! impl_colorize_callback {
|
||||||
($side:ident: $name:ident => $color:path) => {
|
($callback:ident!($args:tt)) => {
|
||||||
fn $name(self) -> StyledContent<&'static str> {
|
// foreground colors
|
||||||
StyledContent::new(
|
$callback!($args, foreground_color: black => Color::Black);
|
||||||
ContentStyle {
|
$callback!($args, foreground_color: dark_grey => Color::DarkGrey);
|
||||||
$side: Some($color),
|
$callback!($args, foreground_color: red => Color::Red);
|
||||||
..Default::default()
|
$callback!($args, foreground_color: dark_red => Color::DarkRed);
|
||||||
},
|
$callback!($args, foreground_color: green => Color::Green);
|
||||||
self,
|
$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! def_char_color {
|
macro_rules! impl_colorize {
|
||||||
($side:ident: $name:ident => $color:path) => {
|
($impl_ty:ty) => {
|
||||||
fn $name(self) -> StyledContent<char> {
|
impl Colorize<$impl_ty> for $impl_ty {
|
||||||
StyledContent::new(
|
impl_colorize_callback!(def_color_base!($impl_ty));
|
||||||
ContentStyle {
|
|
||||||
$side: Some($color),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
self,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! def_str_attr {
|
|
||||||
($name:ident => $attr:path) => {
|
|
||||||
fn $name(self) -> StyledContent<&'static str> {
|
|
||||||
StyledContent::new(
|
|
||||||
ContentStyle {
|
|
||||||
attributes: $attr.into(),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
self,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
macro_rules! def_char_attr {
|
|
||||||
($name:ident => $attr:path) => {
|
|
||||||
fn $name(self) -> StyledContent<char> {
|
|
||||||
StyledContent::new(
|
|
||||||
ContentStyle {
|
|
||||||
attributes: $attr.into(),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
self,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -123,55 +123,11 @@ impl<D: Display> Display for StyledContent<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<D: Display + Clone> Colorize<D> for StyledContent<D> {
|
impl<D: Display + Clone> Colorize<D> for StyledContent<D> {
|
||||||
// foreground colors
|
impl_colorize_callback!(def_color_generic!(()));
|
||||||
def_color!(foreground_color: black => Color::Black);
|
|
||||||
def_color!(foreground_color: dark_grey => Color::DarkGrey);
|
|
||||||
def_color!(foreground_color: red => Color::Red);
|
|
||||||
def_color!(foreground_color: dark_red => Color::DarkRed);
|
|
||||||
def_color!(foreground_color: green => Color::Green);
|
|
||||||
def_color!(foreground_color: dark_green => Color::DarkGreen);
|
|
||||||
def_color!(foreground_color: yellow => Color::Yellow);
|
|
||||||
def_color!(foreground_color: dark_yellow => Color::DarkYellow);
|
|
||||||
def_color!(foreground_color: blue => Color::Blue);
|
|
||||||
def_color!(foreground_color: dark_blue => Color::DarkBlue);
|
|
||||||
def_color!(foreground_color: magenta => Color::Magenta);
|
|
||||||
def_color!(foreground_color: dark_magenta => Color::DarkMagenta);
|
|
||||||
def_color!(foreground_color: cyan => Color::Cyan);
|
|
||||||
def_color!(foreground_color: dark_cyan => Color::DarkCyan);
|
|
||||||
def_color!(foreground_color: white => Color::White);
|
|
||||||
def_color!(foreground_color: grey => Color::Grey);
|
|
||||||
|
|
||||||
// background colors
|
|
||||||
def_color!(background_color: on_black => Color::Black);
|
|
||||||
def_color!(background_color: on_dark_grey => Color::DarkGrey);
|
|
||||||
def_color!(background_color: on_red => Color::Red);
|
|
||||||
def_color!(background_color: on_dark_red => Color::DarkRed);
|
|
||||||
def_color!(background_color: on_green => Color::Green);
|
|
||||||
def_color!(background_color: on_dark_green => Color::DarkGreen);
|
|
||||||
def_color!(background_color: on_yellow => Color::Yellow);
|
|
||||||
def_color!(background_color: on_dark_yellow => Color::DarkYellow);
|
|
||||||
def_color!(background_color: on_blue => Color::Blue);
|
|
||||||
def_color!(background_color: on_dark_blue => Color::DarkBlue);
|
|
||||||
def_color!(background_color: on_magenta => Color::Magenta);
|
|
||||||
def_color!(background_color: on_dark_magenta => Color::DarkMagenta);
|
|
||||||
def_color!(background_color: on_cyan => Color::Cyan);
|
|
||||||
def_color!(background_color: on_dark_cyan => Color::DarkCyan);
|
|
||||||
def_color!(background_color: on_white => Color::White);
|
|
||||||
def_color!(background_color: on_grey => Color::Grey);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<D: Display + Clone> Styler<D> for StyledContent<D> {
|
impl<D: Display + Clone> Styler<D> for StyledContent<D> {
|
||||||
def_attr!(reset => Attribute::Reset);
|
impl_styler_callback!(def_attr_generic!(()));
|
||||||
def_attr!(bold => Attribute::Bold);
|
|
||||||
def_attr!(underlined => Attribute::Underlined);
|
|
||||||
def_attr!(reverse => Attribute::Reverse);
|
|
||||||
def_attr!(dim => Attribute::Dim);
|
|
||||||
def_attr!(italic => Attribute::Italic);
|
|
||||||
def_attr!(negative => Attribute::Reverse);
|
|
||||||
def_attr!(slow_blink => Attribute::SlowBlink);
|
|
||||||
def_attr!(rapid_blink => Attribute::RapidBlink);
|
|
||||||
def_attr!(hidden => Attribute::Hidden);
|
|
||||||
def_attr!(crossed_out => Attribute::CrossedOut);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
Loading…
Reference in New Issue
Block a user