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;
212