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