kutil_cli/debug/
theme.rs

1use {
2    owo_colors::*,
3    std::{fmt, io},
4};
5
6//
7// Theme
8//
9
10/// Collection of theme for printing text.
11///
12/// See [Debuggable](super::debuggable::Debuggable).
13pub struct Theme {
14    /// For bare words: true, false, null, etc.
15    pub bare_style: Style,
16
17    /// For numbers.
18    pub number_style: Style,
19
20    /// For strings and characters.
21    pub string_style: Style,
22
23    /// For names of types, instances, etc.
24    pub name_style: Style,
25
26    /// For metadata.
27    pub meta_style: Style,
28
29    /// For errors.
30    pub error_style: Style,
31
32    /// For headings.
33    pub heading_style: Style,
34
35    /// For delimiters.
36    pub delimiter_style: Style,
37}
38
39impl Theme {
40    /// Plain theme.
41    pub fn plain() -> Self {
42        Self {
43            bare_style: Style::new(),
44            number_style: Style::new(),
45            string_style: Style::new(),
46            name_style: Style::new(),
47            meta_style: Style::new(),
48            error_style: Style::new(),
49            heading_style: Style::new(),
50            delimiter_style: Style::new(),
51        }
52    }
53
54    /// Apply bare style.
55    pub fn bare<ThingT>(&self, thing: ThingT) -> Styled<ThingT> {
56        self.bare_style.style(thing)
57    }
58
59    /// Apply number style.
60    pub fn number<ThingT>(&self, thing: ThingT) -> Styled<ThingT> {
61        self.number_style.style(thing)
62    }
63
64    /// Apply string style.
65    pub fn string<ThingT>(&self, thing: ThingT) -> Styled<ThingT> {
66        self.string_style.style(thing)
67    }
68
69    /// Apply name style.
70    pub fn name<ThingT>(&self, thing: ThingT) -> Styled<ThingT> {
71        self.name_style.style(thing)
72    }
73
74    /// Apply meta style.
75    pub fn meta<ThingT>(&self, thing: ThingT) -> Styled<ThingT> {
76        self.meta_style.style(thing)
77    }
78
79    /// Apply error style.
80    pub fn error<ThingT>(&self, thing: ThingT) -> Styled<ThingT> {
81        self.error_style.style(thing)
82    }
83
84    /// Apply heading style.
85    pub fn heading<ThingT>(&self, thing: ThingT) -> Styled<ThingT> {
86        self.heading_style.style(thing)
87    }
88
89    /// Apply delimiter style.
90    pub fn delimiter<ThingT>(&self, thing: ThingT) -> Styled<ThingT> {
91        self.delimiter_style.style(thing)
92    }
93
94    /// Write [fmt::Display] in bare style.
95    pub fn write_bare<WriteT, ThingT>(&self, writer: &mut WriteT, thing: ThingT) -> io::Result<()>
96    where
97        WriteT: io::Write,
98        ThingT: fmt::Display,
99    {
100        write!(writer, "{}", self.bare(thing))
101    }
102
103    /// Write [fmt::Display] in number style.
104    pub fn write_number<WriteT, ThingT>(&self, writer: &mut WriteT, thing: ThingT) -> io::Result<()>
105    where
106        WriteT: io::Write,
107        ThingT: fmt::Display,
108    {
109        write!(writer, "{}", self.number(thing))
110    }
111
112    /// Write [fmt::Display] in string style.
113    pub fn write_string<WriteT, ThingT>(&self, writer: &mut WriteT, thing: ThingT) -> io::Result<()>
114    where
115        WriteT: io::Write,
116        ThingT: fmt::Display,
117    {
118        write!(writer, "{}", self.string(thing))
119    }
120
121    /// Write [fmt::Display] in name style.
122    pub fn write_name<WriteT, ThingT>(&self, writer: &mut WriteT, thing: ThingT) -> io::Result<()>
123    where
124        WriteT: io::Write,
125        ThingT: fmt::Display,
126    {
127        write!(writer, "{}", self.name(thing))
128    }
129
130    /// Write [fmt::Display] in meta style.
131    pub fn write_meta<WriteT, ThingT>(&self, writer: &mut WriteT, thing: ThingT) -> io::Result<()>
132    where
133        WriteT: io::Write,
134        ThingT: fmt::Display,
135    {
136        write!(writer, "{}", self.meta(thing))
137    }
138
139    /// Write [fmt::Display] in error style.
140    pub fn write_error<WriteT, ThingT>(&self, writer: &mut WriteT, thing: ThingT) -> io::Result<()>
141    where
142        WriteT: io::Write,
143        ThingT: fmt::Display,
144    {
145        write!(writer, "{}", self.error(thing))
146    }
147
148    /// Write [fmt::Display] in heading style.
149    pub fn write_heading<WriteT, ThingT>(&self, writer: &mut WriteT, thing: ThingT) -> io::Result<()>
150    where
151        WriteT: io::Write,
152        ThingT: fmt::Display,
153    {
154        write!(writer, "{}", self.heading(thing))
155    }
156
157    /// Write [fmt::Display] in delimiter style.
158    pub fn write_delimiter<WriteT, ThingT>(&self, writer: &mut WriteT, thing: ThingT) -> io::Result<()>
159    where
160        WriteT: io::Write,
161        ThingT: fmt::Display,
162    {
163        write!(writer, "{}", self.delimiter(thing))
164    }
165}
166
167impl Default for Theme {
168    fn default() -> Self {
169        Self {
170            bare_style: Style::new().yellow(),
171            number_style: Style::new().magenta(),
172            string_style: Style::new().cyan(),
173            name_style: Style::new().green(),
174            meta_style: Style::new().blue().italic(),
175            error_style: Style::new().red().bold(),
176            heading_style: Style::new().green().bold().underline(),
177            delimiter_style: Style::new().dimmed(),
178        }
179    }
180}