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