owo_colors/
colors.rs

1//! Color types for used for being generic over the color
2use crate::{BgColorDisplay, BgDynColorDisplay, FgColorDisplay, FgDynColorDisplay};
3use core::fmt;
4
5macro_rules! colors {
6    ($(
7        $color:ident $fg:literal $bg:literal
8    ),* $(,)?) => {
9
10        pub(crate) mod ansi_colors {
11            use core::fmt;
12
13            #[allow(unused_imports)]
14            use crate::OwoColorize;
15
16            /// Available standard ANSI colors for use with [`OwoColorize::color`](OwoColorize::color)
17            /// or [`OwoColorize::on_color`](OwoColorize::on_color)
18            #[allow(missing_docs)]
19            #[derive(Copy, Clone, Debug, PartialEq, Eq)]
20            pub enum AnsiColors {
21                $(
22                    $color,
23                )*
24            }
25
26            impl crate::DynColor for AnsiColors {
27                fn fmt_ansi_fg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28                    let color = match self {
29                        $(
30                            AnsiColors::$color => concat!("\x1b[", stringify!($fg), "m"),
31                        )*
32                    };
33
34                    write!(f, "{}", color)
35                }
36
37                fn fmt_ansi_bg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
38                    let color = match self {
39                        $(
40                            AnsiColors::$color => concat!("\x1b[", stringify!($bg), "m"),
41                        )*
42                    };
43
44                    write!(f, "{}", color)
45                }
46
47                fn fmt_raw_ansi_fg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48                    let color = match self {
49                        $(
50                            AnsiColors::$color => stringify!($fg),
51                        )*
52                    };
53
54                    f.write_str(color)
55                }
56
57                fn fmt_raw_ansi_bg(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
58                    let color = match self {
59                        $(
60                            AnsiColors::$color => stringify!($bg),
61                        )*
62                    };
63
64                    f.write_str(color)
65                }
66
67                #[doc(hidden)]
68                fn get_dyncolors_fg(&self) -> crate::DynColors {
69                    crate::DynColors::Ansi(*self)
70                }
71
72                #[doc(hidden)]
73                fn get_dyncolors_bg(&self) -> crate::DynColors {
74                    crate::DynColors::Ansi(*self)
75                }
76            }
77        }
78
79        $(
80            /// A color for use with [`OwoColorize`](crate::OwoColorize)'s `fg` and `bg` methods.
81            pub struct $color;
82
83            impl crate::Color for $color {
84                const ANSI_FG: &'static str = concat!("\x1b[", stringify!($fg), "m");
85                const ANSI_BG: &'static str = concat!("\x1b[", stringify!($bg), "m");
86
87                const RAW_ANSI_FG: &'static str = stringify!($fg);
88                const RAW_ANSI_BG: &'static str = stringify!($bg);
89
90                #[doc(hidden)]
91                type DynEquivelant = ansi_colors::AnsiColors;
92
93                #[doc(hidden)]
94                const DYN_EQUIVELANT: Self::DynEquivelant = ansi_colors::AnsiColors::$color;
95
96                #[doc(hidden)]
97                fn into_dyncolors() -> crate::DynColors {
98                    crate::DynColors::Ansi(ansi_colors::AnsiColors::$color)
99                }
100            }
101        )*
102
103    };
104}
105
106colors! {
107    Black   30 40,
108    Red     31 41,
109    Green   32 42,
110    Yellow  33 43,
111    Blue    34 44,
112    Magenta 35 45,
113    Cyan    36 46,
114    White   37 47,
115    Default   39 49,
116
117    BrightBlack   90 100,
118    BrightRed     91 101,
119    BrightGreen   92 102,
120    BrightYellow  93 103,
121    BrightBlue    94 104,
122    BrightMagenta 95 105,
123    BrightCyan    96 106,
124    BrightWhite   97 107,
125}
126
127macro_rules! impl_fmt_for {
128    ($($trait:path),* $(,)?) => {
129        $(
130            impl<'a, Color: crate::Color, T: $trait> $trait for FgColorDisplay<'a, Color, T> {
131                #[inline(always)]
132                fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
133                    f.write_str(Color::ANSI_FG)?;
134                    <T as $trait>::fmt(&self.0, f)?;
135                    f.write_str("\x1b[39m")
136                }
137            }
138
139            impl<'a, Color: crate::Color, T: $trait> $trait for BgColorDisplay<'a, Color, T> {
140                #[inline(always)]
141                fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
142                    f.write_str(Color::ANSI_BG)?;
143                    <T as $trait>::fmt(&self.0, f)?;
144                    f.write_str("\x1b[49m")
145                }
146            }
147        )*
148    };
149}
150
151impl_fmt_for! {
152    fmt::Display,
153    fmt::Debug,
154    fmt::UpperHex,
155    fmt::LowerHex,
156    fmt::Binary,
157    fmt::UpperExp,
158    fmt::LowerExp,
159    fmt::Octal,
160    fmt::Pointer,
161}
162
163macro_rules! impl_fmt_for_dyn {
164    ($($trait:path),* $(,)?) => {
165        $(
166            impl<'a, Color: crate::DynColor, T: $trait> $trait for FgDynColorDisplay<'a, Color, T> {
167                #[inline(always)]
168                fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
169                    (self.1).fmt_ansi_fg(f)?;
170                    <T as $trait>::fmt(&self.0, f)?;
171                    f.write_str("\x1b[39m")
172                }
173            }
174
175            impl<'a, Color: crate::DynColor, T: $trait> $trait for BgDynColorDisplay<'a, Color, T> {
176                #[inline(always)]
177                fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
178                    (self.1).fmt_ansi_bg(f)?;
179                    <T as $trait>::fmt(&self.0, f)?;
180                    f.write_str("\x1b[49m")
181                }
182            }
183        )*
184    };
185}
186
187impl_fmt_for_dyn! {
188    fmt::Display,
189    fmt::Debug,
190    fmt::UpperHex,
191    fmt::LowerHex,
192    fmt::Binary,
193    fmt::UpperExp,
194    fmt::LowerExp,
195    fmt::Octal,
196    fmt::Pointer,
197}
198
199/// CSS named colors. Not as widely supported as standard ANSI as it relies on 48bit color support.
200///
201/// Reference: <https://www.w3schools.com/cssref/css_colors.asp>
202/// Reference: <https://developer.mozilla.org/en-US/docs/Web/CSS/color_value>
203pub mod css;
204/// XTerm 256-bit colors. Not as widely supported as standard ANSI but contains 240 more colors.
205pub mod xterm;
206
207mod custom;
208
209pub use custom::CustomColor;
210
211pub(crate) mod dynamic;