1pub use inner::Color;
9
10#[non_exhaustive]
30#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
31pub struct Colors {
32 pub branches: Option<Color>,
34 pub vertical: Option<Color>,
36 pub keywords: Option<Color>,
38 pub members: Option<Color>,
40 pub strings: Option<Color>,
42 pub values: Option<Color>,
44 pub types: Option<Color>,
46}
47
48impl Colors {
51 pub const NONE: Self = Self::new();
53
54 pub const VSCODE_DARK_PLUS: Self = Self::new()
56 .branches(Some(inner::ansi256(32)))
57 .vertical(Some(inner::ansi256(24)))
58 .keywords(Some(inner::ansi256(74)))
59 .members(Some(inner::ansi256(153)))
60 .strings(Some(inner::ansi256(173)))
61 .values(Some(inner::ansi256(187)))
62 .types(Some(inner::ansi256(79)));
63
64 pub const VSCODE_LIGHT_PLUS: Self = Self::new()
66 .branches(Some(inner::ansi256(28)))
67 .vertical(Some(inner::ansi256(23)))
68 .keywords(Some(inner::ansi256(133)))
69 .members(Some(inner::ansi256(25)))
70 .strings(Some(inner::ansi256(88)))
71 .values(Some(inner::ansi256(94)))
72 .types(Some(inner::ansi256(26)));
73
74 pub const SOLARIZED_DARK: Self = Self::new()
76 .branches(Some(inner::ansi256(101)))
77 .vertical(Some(inner::ansi256(60)))
78 .keywords(Some(inner::ansi256(33)))
79 .members(Some(inner::ansi256(112)))
80 .strings(Some(inner::ansi256(106)))
81 .values(Some(inner::ansi256(179)))
82 .types(Some(inner::ansi256(68)));
83
84 pub const SOLARIZED_LIGHT: Self = Self::new()
86 .branches(Some(inner::ansi256(101)))
87 .vertical(Some(inner::ansi256(60)))
88 .keywords(Some(inner::ansi256(33)))
89 .members(Some(inner::ansi256(112)))
90 .strings(Some(inner::ansi256(106)))
91 .values(Some(inner::ansi256(179)))
92 .types(Some(inner::ansi256(68)));
93
94 pub const DRACULA: Self = Self::new()
96 .branches(Some(inner::ansi256(102)))
97 .vertical(Some(inner::ansi256(59)))
98 .keywords(Some(inner::ansi256(141)))
99 .members(Some(inner::ansi256(147)))
100 .strings(Some(inner::ansi256(114)))
101 .values(Some(inner::ansi256(186)))
102 .types(Some(inner::ansi256(147)));
103
104 pub const MONOKAI: Self = Self::new()
106 .branches(Some(inner::ansi256(144)))
107 .vertical(Some(inner::ansi256(59)))
108 .keywords(Some(inner::ansi256(204)))
109 .members(Some(inner::ansi256(147)))
110 .strings(Some(inner::ansi256(113)))
111 .values(Some(inner::ansi256(186)))
112 .types(Some(inner::ansi256(147)));
113
114 pub const NORD: Self = Self::new()
116 .branches(Some(inner::ansi256(109)))
117 .vertical(Some(inner::ansi256(66)))
118 .keywords(Some(inner::ansi256(117)))
119 .members(Some(inner::ansi256(148)))
120 .strings(Some(inner::ansi256(150)))
121 .values(Some(inner::ansi256(179)))
122 .types(Some(inner::ansi256(148)));
123
124 pub const GITHUB_DARK: Self = Self::new()
126 .branches(Some(inner::ansi256(102)))
127 .vertical(Some(inner::ansi256(59)))
128 .keywords(Some(inner::ansi256(204)))
129 .members(Some(inner::ansi256(117)))
130 .strings(Some(inner::ansi256(142)))
131 .values(Some(inner::ansi256(186)))
132 .types(Some(inner::ansi256(117)));
133
134 pub const GITHUB_LIGHT: Self = Self::new()
136 .branches(Some(inner::ansi256(102)))
137 .vertical(Some(inner::ansi256(59)))
138 .keywords(Some(inner::ansi256(204)))
139 .members(Some(inner::ansi256(26)))
140 .strings(Some(inner::ansi256(142)))
141 .values(Some(inner::ansi256(186)))
142 .types(Some(inner::ansi256(26)));
143}
144
145impl Colors {
148 pub const fn new() -> Self {
150 Self {
151 branches: None,
152 vertical: None,
153 keywords: None,
154 members: None,
155 strings: None,
156 values: None,
157 types: None,
158 }
159 }
160
161 pub const fn branches(mut self, color: Option<Color>) -> Self {
168 self.branches = color;
169 self
170 }
171
172 pub const fn vertical(mut self, color: Option<Color>) -> Self {
179 self.vertical = color;
180 self
181 }
182
183 pub const fn keywords(mut self, color: Option<Color>) -> Self {
189 self.keywords = color;
190 self
191 }
192
193 pub const fn members(mut self, color: Option<Color>) -> Self {
200 self.members = color;
201 self
202 }
203
204 pub const fn strings(mut self, color: Option<Color>) -> Self {
210 self.strings = color;
211 self
212 }
213
214 pub const fn values(mut self, color: Option<Color>) -> Self {
221 self.values = color;
222 self
223 }
224
225 pub const fn types(mut self, color: Option<Color>) -> Self {
232 self.types = color;
233 self
234 }
235
236 pub const fn all(mut self, color: Option<Color>) -> Self {
243 self.branches = color;
244 self.vertical = color;
245 self.keywords = color;
246 self.members = color;
247 self.strings = color;
248 self.values = color;
249 self.types = color;
250 self
251 }
252}
253
254impl Default for Colors {
255 fn default() -> Self {
257 Self::VSCODE_DARK_PLUS
258 }
259}
260
261pub(crate) trait Colored {
264 fn fg(&self, color: Option<Color>) -> String;
265 fn stripped(&self) -> String;
266}
267
268#[cfg(feature = "color")]
269mod inner {
270 pub use anstyle::Color;
271
272 pub(crate) const fn ansi256(color: u8) -> Color {
273 Color::Ansi256(anstyle::Ansi256Color(color))
274 }
275
276 impl<T: AsRef<str>> super::Colored for T {
277 fn fg(&self, color: Option<Color>) -> String {
278 let style = anstyle::Style::new().fg_color(color);
279 let style_intro = style.render().to_string();
280 let style_reset = style.render_reset().to_string();
281 format!("{}{}{}", style_intro, self.as_ref(), style_reset)
282 }
283
284 fn stripped(&self) -> String {
285 use anstream::adapter::strip_str;
286 strip_str(self.as_ref()).to_string()
287 }
288 }
289}
290
291#[cfg(not(feature = "color"))]
292mod inner {
293 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
298 pub struct Color;
299
300 pub(crate) const fn ansi256(_: u8) -> Color {
301 Color
302 }
303
304 impl<T: AsRef<str>> super::Colored for T {
305 fn fg(&self, _: Option<Color>) -> String {
306 self.as_ref().to_string()
307 }
308
309 fn stripped(&self) -> String {
310 self.as_ref().to_string()
311 }
312 }
313}