cod/style.rs
1//! Utilities for modifying the look of the text.
2//!
3//! Note that faint and bold are mutually exclusive on some terminals, thus
4//! [`de::weight`] resets both simultaneously. This behavior extends to
5//! [`with::bold`] and [`with::faint`].
6
7use crate::escape;
8
9macro_rules! do_style {
10 ( $( $style:ident: $code:tt ),+ ) => {
11 $(
12 /// Enable
13 #[doc = concat!(stringify!($style), ".")]
14 pub fn $style() {
15 escape(concat!(stringify!($code), "m"));
16 }
17 )+
18 };
19}
20
21do_style!(bold: 1, faint: 2, italic: 3, underline: 4, strike: 9);
22
23/// Reset styling.
24pub mod de {
25 use crate::escape;
26
27 macro_rules! de_style {
28 ( $( $style:ident: $code:tt ),+ ) => {
29 $(
30 /// Disable
31 #[doc = concat!(stringify!($style), ".")]
32 pub fn $style() {
33 escape(concat!(stringify!($code), "m"));
34 }
35 )+
36
37 /// Disable all style attributes.
38 pub fn all() {
39 $($style();)+
40 weight();
41 }
42 };
43 }
44
45 de_style!(italic: 23, underline: 24, strike: 29);
46
47 /// Disables both bold and faint styling.
48 ///
49 /// See module documentation for why.
50 pub fn weight() {
51 escape("22m");
52 }
53}
54
55/// Style your text through closures.
56///
57/// Example:
58///
59/// ```
60/// # use cod::style;
61/// style::italic();
62/// style::with::bold(|| {
63/// println!("I'm italic and bold!");
64/// });
65///
66/// println!("I'm italic!");
67/// ```
68pub mod with {
69 macro_rules! with_style {
70 ( $( $style:ident: $de:ident ),+ ) => {
71 $(
72 /// Enable
73 #[doc = concat!(stringify!($style), ",")]
74 /// then run the function, then disable it again.
75 pub fn $style(f: impl FnOnce()) {
76 super::$style();
77 (f)();
78 super::de::$de();
79 }
80 )+
81 };
82 }
83
84 with_style![
85 bold: weight,
86 faint: weight,
87 italic: italic,
88 underline: underline,
89 strike: strike
90 ];
91}