1use crate::background_colors::BackgroundColors;
2use crate::font_mode::FontMode;
3use std::fmt;
4use std::ops::Add;
5
6pub enum ForegroundColors {
7 Black(&'static str),
8 Red(&'static str),
9 Green(&'static str),
10 Yellow(&'static str),
11 Blue(&'static str),
12 Magenta(&'static str),
13 Cyan(&'static str),
14 White(&'static str),
15 Default(&'static str),
16 BrightBlack(&'static str),
17 BrightRed(&'static str),
18 BrightGreen(&'static str),
19 BrightYellow(&'static str),
20 BrightBlue(&'static str),
21 BrightMagenta(&'static str),
22 BrightCyan(&'static str),
23 BrightWhite(&'static str),
24}
25
26impl ForegroundColors {
27 pub fn black() -> Self {
28 ForegroundColors::Black("\x1B[30m")
29 }
30
31 pub fn red() -> Self {
32 ForegroundColors::Red("\x1B[31m")
33 }
34
35 pub fn green() -> Self {
36 ForegroundColors::Green("\x1B[32m")
37 }
38
39 pub fn yellow() -> Self {
40 ForegroundColors::Yellow("\x1B[33m")
41 }
42
43 pub fn blue() -> Self {
44 ForegroundColors::Blue("\x1B[34m")
45 }
46
47 pub fn magenta() -> Self {
48 ForegroundColors::Magenta("\x1B[35m")
49 }
50
51 pub fn cyan() -> Self {
52 ForegroundColors::Cyan("\x1B[36m")
53 }
54
55 pub fn white() -> Self {
56 ForegroundColors::White("\x1B[37m")
57 }
58
59 pub fn default() -> Self {
60 ForegroundColors::Default("\x1B[39m")
61 }
62
63 pub fn bright_black() -> Self {
64 ForegroundColors::BrightBlack("\x1B[90m")
65 }
66
67 pub fn bright_red() -> Self {
68 ForegroundColors::BrightRed("\x1B[91m")
69 }
70
71 pub fn bright_green() -> Self {
72 ForegroundColors::BrightGreen("\x1B[92m")
73 }
74
75 pub fn bright_yellow() -> Self {
76 ForegroundColors::BrightYellow("\x1B[93m")
77 }
78
79 pub fn bright_blue() -> Self {
80 ForegroundColors::BrightBlue("\x1B[94m")
81 }
82
83 pub fn bright_magenta() -> Self {
84 ForegroundColors::BrightMagenta("\x1B[95m")
85 }
86
87 pub fn bright_cyan() -> Self {
88 ForegroundColors::BrightCyan("\x1B[96m")
89 }
90
91 pub fn bright_white() -> Self {
92 ForegroundColors::BrightWhite("\x1B[97m")
93 }
94}
95
96impl fmt::Display for ForegroundColors {
97 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 match self {
99 ForegroundColors::Black(s) => write!(f, "{}", s),
100 ForegroundColors::Red(s) => write!(f, "{}", s),
101 ForegroundColors::Green(s) => write!(f, "{}", s),
102 ForegroundColors::Yellow(s) => write!(f, "{}", s),
103 ForegroundColors::Blue(s) => write!(f, "{}", s),
104 ForegroundColors::Magenta(s) => write!(f, "{}", s),
105 ForegroundColors::Cyan(s) => write!(f, "{}", s),
106 ForegroundColors::White(s) => write!(f, "{}", s),
107 ForegroundColors::Default(s) => write!(f, "{}", s),
108 ForegroundColors::BrightBlack(s) => write!(f, "{}", s),
109 ForegroundColors::BrightRed(s) => write!(f, "{}", s),
110 ForegroundColors::BrightGreen(s) => write!(f, "{}", s),
111 ForegroundColors::BrightYellow(s) => write!(f, "{}", s),
112 ForegroundColors::BrightBlue(s) => write!(f, "{}", s),
113 ForegroundColors::BrightMagenta(s) => write!(f, "{}", s),
114 ForegroundColors::BrightCyan(s) => write!(f, "{}", s),
115 ForegroundColors::BrightWhite(s) => write!(f, "{}", s),
116 }
117 }
118}
119
120impl Add<BackgroundColors> for ForegroundColors {
121 type Output = String;
122
123 fn add(self, rhs: BackgroundColors) -> Self::Output {
124 let foreground_color = self.to_string().replace("\x1B[", "").replace("m", "");
125 let background_color = rhs.to_string().replace("\x1B[", "").replace("m", "");
126
127 format!("\x1B[{};{}m", foreground_color, background_color)
128 }
129}
130
131impl Add<FontMode> for ForegroundColors {
132 type Output = String;
133
134 fn add(self, rhs: FontMode) -> Self::Output {
135 let foreground_color = self.to_string().replace("\x1B[", "").replace("m", "");
136 let font_mode = rhs.to_string().replace("\x1B[", "").replace("m", "");
137
138 format!("\x1B[{};{}m", foreground_color, font_mode)
139 }
140}
141
142impl Add<ForegroundColors> for ForegroundColors {
143 type Output = String;
144
145 fn add(self, rhs: ForegroundColors) -> Self::Output {
146 let foreground_color_lhs = self.to_string().replace("\x1B[", "").replace("m", "");
147 let foreground_color_rhs = rhs.to_string().replace("\x1B[", "").replace("m", "");
148
149 format!("\x1B[{};{}m", foreground_color_lhs, foreground_color_rhs)
150 }
151}
152
153impl Add<String> for ForegroundColors {
154 type Output = String;
155
156 fn add(self, rhs: String) -> Self::Output {
157 let foreground_color = self.to_string().replace("\x1B[", "").replace("m", "");
158 let string = rhs.to_string().replace("\x1B[", "").replace("m", "");
159
160 format!("\x1B[{};{}m", foreground_color, string)
161 }
162}
163
164impl Add<ForegroundColors> for String {
165 type Output = String;
166
167 fn add(self, rhs: ForegroundColors) -> Self::Output {
168 let string = self.to_string().replace("\x1B[", "").replace("m", "");
169 let foreground_color = rhs.to_string().replace("\x1B[", "").replace("m", "");
170
171 format!("\x1B[{};{}m", string, foreground_color)
172 }
173}
174
175#[cfg(test)]
176mod tests {
177 use super::*;
178
179 #[test]
180 fn test_black() {
181 assert_eq!("\x1B[30m", ForegroundColors::black().to_string());
182 }
183
184 #[test]
185 fn test_red() {
186 assert_eq!("\x1B[31m", ForegroundColors::red().to_string());
187 }
188
189 #[test]
190 fn test_green() {
191 assert_eq!("\x1B[32m", ForegroundColors::green().to_string());
192 }
193
194 #[test]
195 fn test_yellow() {
196 assert_eq!("\x1B[33m", ForegroundColors::yellow().to_string());
197 }
198
199 #[test]
200 fn test_blue() {
201 assert_eq!("\x1B[34m", ForegroundColors::blue().to_string());
202 }
203
204 #[test]
205 fn test_magenta() {
206 assert_eq!("\x1B[35m", ForegroundColors::magenta().to_string());
207 }
208
209 #[test]
210 fn test_cyan() {
211 assert_eq!("\x1B[36m", ForegroundColors::cyan().to_string());
212 }
213
214 #[test]
215 fn test_white() {
216 assert_eq!("\x1B[37m", ForegroundColors::white().to_string());
217 }
218
219 #[test]
220 fn test_default() {
221 assert_eq!("\x1B[39m", ForegroundColors::default().to_string());
222 }
223
224 #[test]
225 fn test_bright_black() {
226 assert_eq!("\x1B[90m", ForegroundColors::bright_black().to_string());
227 }
228
229 #[test]
230 fn test_bright_red() {
231 assert_eq!("\x1B[91m", ForegroundColors::bright_red().to_string());
232 }
233
234 #[test]
235 fn test_bright_green() {
236 assert_eq!("\x1B[92m", ForegroundColors::bright_green().to_string());
237 }
238
239 #[test]
240 fn test_bright_yellow() {
241 assert_eq!("\x1B[93m", ForegroundColors::bright_yellow().to_string());
242 }
243
244 #[test]
245 fn test_bright_blue() {
246 assert_eq!("\x1B[94m", ForegroundColors::bright_blue().to_string());
247 }
248
249 #[test]
250 fn test_bright_magenta() {
251 assert_eq!("\x1B[95m", ForegroundColors::bright_magenta().to_string());
252 }
253
254 #[test]
255 fn test_bright_cyan() {
256 assert_eq!("\x1B[96m", ForegroundColors::bright_cyan().to_string());
257 }
258
259 #[test]
260 fn test_bright_white() {
261 assert_eq!("\x1B[97m", ForegroundColors::bright_white().to_string());
262 }
263
264 #[test]
265 fn test_foreground_color_add_foreground_color() {
266 let foreground_color_one = ForegroundColors::cyan();
267 let foreground_color_two = ForegroundColors::magenta();
268
269 assert_eq!("\x1B[36;35m", foreground_color_one + foreground_color_two);
270 }
271
272 #[test]
273 fn test_foreground_color_add_background_color() {
274 let foreground_color = ForegroundColors::cyan();
275 let background_color = BackgroundColors::magenta();
276
277 assert_eq!("\x1B[36;45m", foreground_color + background_color);
278 }
279
280 #[test]
281 fn test_foreground_color_add_font_mode() {
282 let foreground_color = ForegroundColors::cyan();
283 let font_mode = FontMode::underline();
284
285 assert_eq!("\x1B[36;4m", foreground_color + font_mode);
286 }
287
288 #[test]
289 fn test_foreground_color_add_string() {
290 let foreground_color = ForegroundColors::cyan();
291 let string = BackgroundColors::black() + FontMode::strikethrough();
292
293 assert_eq!("\x1B[36;40;9m", foreground_color + string);
294 }
295
296 #[test]
297 fn test_string_add_foreground_color() {
298 let string = BackgroundColors::black() + FontMode::strikethrough();
299 let foreground_color = ForegroundColors::cyan();
300
301 assert_eq!("\x1B[40;9;36m", string + foreground_color);
302 }
303}