facet_ansi/
lib.rs

1#![warn(missing_docs)]
2#![warn(clippy::std_instead_of_core)]
3#![warn(clippy::std_instead_of_alloc)]
4#![forbid(unsafe_code)]
5#![doc = include_str!("../README.md")]
6
7use core::fmt::{self, Debug, Display, Formatter};
8
9use anstyle::AnsiColor;
10// Re-export Style from anstyle
11pub use anstyle::Style;
12
13/// Provides easy access to common styles
14pub mod styles {
15    use super::*;
16
17    /// Get a red style
18    pub fn red() -> Style {
19        Style::new().fg_red()
20    }
21
22    /// Get a green style
23    pub fn green() -> Style {
24        Style::new().fg_green()
25    }
26
27    /// Get a blue style
28    pub fn blue() -> Style {
29        Style::new().fg_blue()
30    }
31
32    /// Get a yellow style
33    pub fn yellow() -> Style {
34        Style::new().fg_yellow()
35    }
36
37    /// Get a magenta style
38    pub fn magenta() -> Style {
39        Style::new().fg_magenta()
40    }
41
42    /// Get a cyan style
43    pub fn cyan() -> Style {
44        Style::new().fg_cyan()
45    }
46
47    /// Get a white style
48    pub fn white() -> Style {
49        Style::new().fg_white()
50    }
51
52    /// Get a black style
53    pub fn black() -> Style {
54        Style::new().fg_black()
55    }
56
57    /// Get a bright red style
58    pub fn bright_red() -> Style {
59        Style::new().fg_bright_red()
60    }
61
62    /// Get a bright green style
63    pub fn bright_green() -> Style {
64        Style::new().fg_bright_green()
65    }
66
67    /// Get a bright blue style
68    pub fn bright_blue() -> Style {
69        Style::new().fg_bright_blue()
70    }
71
72    /// Get a bright yellow style
73    pub fn bright_yellow() -> Style {
74        Style::new().fg_bright_yellow()
75    }
76
77    /// Get a bright magenta style
78    pub fn bright_magenta() -> Style {
79        Style::new().fg_bright_magenta()
80    }
81
82    /// Get a bright cyan style
83    pub fn bright_cyan() -> Style {
84        Style::new().fg_bright_cyan()
85    }
86
87    /// Get a bright white style
88    pub fn bright_white() -> Style {
89        Style::new().fg_bright_white()
90    }
91
92    /// Get a bold style
93    pub fn bold() -> Style {
94        Style::new().bold()
95    }
96
97    /// Get an underlined style
98    pub fn underline() -> Style {
99        Style::new().underline()
100    }
101
102    /// Get a dimmed style
103    pub fn dimmed() -> Style {
104        Style::new().dimmed()
105    }
106}
107
108/// Extensions for creating styles with common colors
109pub trait ColorStyle {
110    /// Create a new style with red foreground color
111    fn fg_red(self) -> Style;
112    /// Create a new style with green foreground color
113    fn fg_green(self) -> Style;
114    /// Create a new style with blue foreground color
115    fn fg_blue(self) -> Style;
116    /// Create a new style with yellow foreground color
117    fn fg_yellow(self) -> Style;
118    /// Create a new style with magenta foreground color
119    fn fg_magenta(self) -> Style;
120    /// Create a new style with cyan foreground color
121    fn fg_cyan(self) -> Style;
122    /// Create a new style with white foreground color
123    fn fg_white(self) -> Style;
124    /// Create a new style with black foreground color
125    fn fg_black(self) -> Style;
126    /// Create a new style with bright red foreground color
127    fn fg_bright_red(self) -> Style;
128    /// Create a new style with bright green foreground color
129    fn fg_bright_green(self) -> Style;
130    /// Create a new style with bright blue foreground color
131    fn fg_bright_blue(self) -> Style;
132    /// Create a new style with bright yellow foreground color
133    fn fg_bright_yellow(self) -> Style;
134    /// Create a new style with bright magenta foreground color
135    fn fg_bright_magenta(self) -> Style;
136    /// Create a new style with bright cyan foreground color
137    fn fg_bright_cyan(self) -> Style;
138    /// Create a new style with bright white foreground color
139    fn fg_bright_white(self) -> Style;
140    /// Create a new style with bold formatting
141    fn with_bold(self) -> Style;
142    /// Create a new style with dimmed formatting
143    fn with_dimmed(self) -> Style;
144    /// Create a new style with underline formatting
145    fn with_underline(self) -> Style;
146}
147
148impl ColorStyle for Style {
149    fn fg_red(self) -> Style {
150        self.fg_color(Some(anstyle::Color::Ansi(anstyle::AnsiColor::Red)))
151    }
152
153    fn fg_green(self) -> Style {
154        self.fg_color(Some(anstyle::Color::Ansi(anstyle::AnsiColor::Green)))
155    }
156
157    fn fg_blue(self) -> Style {
158        self.fg_color(Some(anstyle::Color::Ansi(anstyle::AnsiColor::Blue)))
159    }
160
161    fn fg_yellow(self) -> Style {
162        self.fg_color(Some(anstyle::Color::Ansi(anstyle::AnsiColor::Yellow)))
163    }
164
165    fn fg_magenta(self) -> Style {
166        self.fg_color(Some(anstyle::Color::Ansi(anstyle::AnsiColor::Magenta)))
167    }
168
169    fn fg_cyan(self) -> Style {
170        self.fg_color(Some(anstyle::Color::Ansi(anstyle::AnsiColor::Cyan)))
171    }
172
173    fn fg_white(self) -> Style {
174        self.fg_color(Some(anstyle::Color::Ansi(anstyle::AnsiColor::White)))
175    }
176
177    fn fg_black(self) -> Style {
178        self.fg_color(Some(anstyle::Color::Ansi(anstyle::AnsiColor::Black)))
179    }
180
181    fn fg_bright_red(self) -> Style {
182        self.fg_color(Some(anstyle::Color::Ansi(anstyle::AnsiColor::BrightRed)))
183    }
184
185    fn fg_bright_green(self) -> Style {
186        self.fg_color(Some(anstyle::Color::Ansi(anstyle::AnsiColor::BrightGreen)))
187    }
188
189    fn fg_bright_blue(self) -> Style {
190        self.fg_color(Some(anstyle::Color::Ansi(anstyle::AnsiColor::BrightBlue)))
191    }
192
193    fn fg_bright_yellow(self) -> Style {
194        self.fg_color(Some(anstyle::Color::Ansi(anstyle::AnsiColor::BrightYellow)))
195    }
196
197    fn fg_bright_magenta(self) -> Style {
198        self.fg_color(Some(anstyle::Color::Ansi(
199            anstyle::AnsiColor::BrightMagenta,
200        )))
201    }
202
203    fn fg_bright_cyan(self) -> Style {
204        self.fg_color(Some(anstyle::Color::Ansi(anstyle::AnsiColor::BrightCyan)))
205    }
206
207    fn fg_bright_white(self) -> Style {
208        self.fg_color(Some(anstyle::Color::Ansi(anstyle::AnsiColor::BrightWhite)))
209    }
210
211    fn with_bold(self) -> Style {
212        self.bold()
213    }
214
215    fn with_dimmed(self) -> Style {
216        self.dimmed()
217    }
218
219    fn with_underline(self) -> Style {
220        self.underline()
221    }
222}
223
224/// A struct that wraps a value and its style.
225pub struct Styled<T> {
226    value: T,
227    style: Style,
228}
229
230impl<T: Display> Display for Styled<T> {
231    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
232        if self.style == Style::new() {
233            Display::fmt(&self.value, f)
234        } else {
235            write!(f, "{}", self.style)?;
236            Display::fmt(&self.value, f)?;
237            write!(f, "{}", anstyle::Reset)
238        }
239    }
240}
241
242impl<T: Debug> Debug for Styled<T> {
243    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
244        if self.style == Style::new() {
245            Debug::fmt(&self.value, f)
246        } else {
247            write!(f, "{}", self.style)?;
248            Debug::fmt(&self.value, f)?;
249            write!(f, "{}", anstyle::Reset)
250        }
251    }
252}
253
254impl<T: fmt::Binary> fmt::Binary for Styled<T> {
255    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
256        if self.style == Style::new() {
257            fmt::Binary::fmt(&self.value, f)
258        } else {
259            write!(f, "{}", self.style)?;
260            fmt::Binary::fmt(&self.value, f)?;
261            write!(f, "{}", anstyle::Reset)
262        }
263    }
264}
265
266impl<T: fmt::Pointer> fmt::Pointer for Styled<T> {
267    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
268        if self.style == Style::new() {
269            fmt::Pointer::fmt(&self.value, f)
270        } else {
271            write!(f, "{}", self.style)?;
272            fmt::Pointer::fmt(&self.value, f)?;
273            write!(f, "{}", anstyle::Reset)
274        }
275    }
276}
277
278/// Extension trait for styling any Display value.
279pub trait Stylize {
280    /// Apply a style to a value.
281    fn style(self, style: Style) -> Styled<Self>
282    where
283        Self: Sized;
284
285    /// Apply red color style to a value.
286    fn red(self) -> Styled<Self>
287    where
288        Self: Sized;
289
290    /// Apply green color style to a value.
291    fn green(self) -> Styled<Self>
292    where
293        Self: Sized;
294
295    /// Apply blue color style to a value.
296    fn blue(self) -> Styled<Self>
297    where
298        Self: Sized;
299
300    /// Apply yellow color style to a value.
301    fn yellow(self) -> Styled<Self>
302    where
303        Self: Sized;
304
305    /// Apply magenta color style to a value.
306    fn magenta(self) -> Styled<Self>
307    where
308        Self: Sized;
309
310    /// Apply cyan color style to a value.
311    fn cyan(self) -> Styled<Self>
312    where
313        Self: Sized;
314
315    /// Apply white color style to a value.
316    fn white(self) -> Styled<Self>
317    where
318        Self: Sized;
319
320    /// Apply black color style to a value.
321    fn black(self) -> Styled<Self>
322    where
323        Self: Sized;
324
325    /// Apply bright red color style to a value.
326    fn bright_red(self) -> Styled<Self>
327    where
328        Self: Sized;
329
330    /// Apply bright green color style to a value.
331    fn bright_green(self) -> Styled<Self>
332    where
333        Self: Sized;
334
335    /// Apply bright blue color style to a value.
336    fn bright_blue(self) -> Styled<Self>
337    where
338        Self: Sized;
339
340    /// Apply bright yellow color style to a value.
341    fn bright_yellow(self) -> Styled<Self>
342    where
343        Self: Sized;
344
345    /// Apply bright magenta color style to a value.
346    fn bright_magenta(self) -> Styled<Self>
347    where
348        Self: Sized;
349
350    /// Apply bright cyan color style to a value.
351    fn bright_cyan(self) -> Styled<Self>
352    where
353        Self: Sized;
354
355    /// Apply bright white color style to a value.
356    fn bright_white(self) -> Styled<Self>
357    where
358        Self: Sized;
359
360    /// Apply bold style to a value.
361    fn bold(self) -> Styled<Self>
362    where
363        Self: Sized;
364
365    /// Apply underline style to a value.
366    fn underline(self) -> Styled<Self>
367    where
368        Self: Sized;
369
370    /// Apply italic style to a value.
371    fn italic(self) -> Styled<Self>
372    where
373        Self: Sized;
374
375    /// Apply dimmed style to a value.
376    fn dim(self) -> Styled<Self>
377    where
378        Self: Sized;
379
380    /// Apply black background style to a value.
381    fn on_black(self) -> Styled<Self>
382    where
383        Self: Sized;
384}
385
386impl<T> Stylize for T {
387    fn style(self, style: Style) -> Styled<Self> {
388        Styled { value: self, style }
389    }
390
391    fn red(self) -> Styled<Self> {
392        self.style(Style::new().fg_red())
393    }
394
395    fn green(self) -> Styled<Self> {
396        self.style(Style::new().fg_green())
397    }
398
399    fn blue(self) -> Styled<Self> {
400        self.style(Style::new().fg_blue())
401    }
402
403    fn yellow(self) -> Styled<Self> {
404        self.style(Style::new().fg_yellow())
405    }
406
407    fn magenta(self) -> Styled<Self> {
408        self.style(Style::new().fg_magenta())
409    }
410
411    fn cyan(self) -> Styled<Self> {
412        self.style(Style::new().fg_cyan())
413    }
414
415    fn white(self) -> Styled<Self> {
416        self.style(Style::new().fg_white())
417    }
418
419    fn black(self) -> Styled<Self> {
420        self.style(Style::new().fg_black())
421    }
422
423    fn bright_red(self) -> Styled<Self> {
424        self.style(Style::new().fg_bright_red())
425    }
426
427    fn bright_green(self) -> Styled<Self> {
428        self.style(Style::new().fg_bright_green())
429    }
430
431    fn bright_blue(self) -> Styled<Self> {
432        self.style(Style::new().fg_bright_blue())
433    }
434
435    fn bright_yellow(self) -> Styled<Self> {
436        self.style(Style::new().fg_bright_yellow())
437    }
438
439    fn bright_magenta(self) -> Styled<Self> {
440        self.style(Style::new().fg_bright_magenta())
441    }
442
443    fn bright_cyan(self) -> Styled<Self> {
444        self.style(Style::new().fg_bright_cyan())
445    }
446
447    fn bright_white(self) -> Styled<Self> {
448        self.style(Style::new().fg_bright_white())
449    }
450
451    fn bold(self) -> Styled<Self> {
452        self.style(Style::new().bold())
453    }
454
455    fn underline(self) -> Styled<Self> {
456        self.style(Style::new().underline())
457    }
458
459    fn italic(self) -> Styled<Self> {
460        self.style(Style::new().italic())
461    }
462
463    fn dim(self) -> Styled<Self> {
464        self.style(Style::new().dimmed())
465    }
466
467    fn on_black(self) -> Styled<Self> {
468        self.style(Style::new().bg_color(Some(anstyle::Color::Ansi(AnsiColor::Black))))
469    }
470}