1use std::fmt::{self, Debug};
2
3use gpui::Hsla;
4use theme::{
5 Appearance, PlayerColor, PlayerColors, StatusColorsRefinement, SystemColors,
6 ThemeColorsRefinement, UserHighlightStyle, UserSyntaxTheme, UserTheme, UserThemeFamily,
7 UserThemeStylesRefinement,
8};
9
10use crate::color::pack_color;
11
12struct RawSyntaxPrinter<'a>(&'a str);
13
14impl<'a> Debug for RawSyntaxPrinter<'a> {
15 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16 write!(f, "{}", self.0)
17 }
18}
19
20struct HslaPrinter(Hsla);
21
22impl Debug for HslaPrinter {
23 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24 write!(f, "rgba({:#010x}).into()", pack_color(self.0))
25 }
26}
27
28struct IntoPrinter<'a, D: Debug>(&'a D);
29
30impl<'a, D: Debug> Debug for IntoPrinter<'a, D> {
31 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32 write!(f, "{:?}.into()", self.0)
33 }
34}
35
36pub struct OptionPrinter<'a, T>(&'a Option<T>);
37
38impl<'a, T: Debug> Debug for OptionPrinter<'a, T> {
39 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
40 match self.0 {
41 Some(value) => write!(f, "Some({:?})", value),
42 None => write!(f, "None"),
43 }
44 }
45}
46
47pub struct VecPrinter<'a, T>(&'a Vec<T>);
48
49impl<'a, T: Debug> Debug for VecPrinter<'a, T> {
50 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51 write!(f, "vec!{:?}", &self.0)
52 }
53}
54
55pub struct UserThemeFamilyPrinter(UserThemeFamily);
56
57impl UserThemeFamilyPrinter {
58 pub fn new(theme_family: UserThemeFamily) -> Self {
59 Self(theme_family)
60 }
61}
62
63impl Debug for UserThemeFamilyPrinter {
64 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65 f.debug_struct("UserThemeFamily")
66 .field("name", &IntoPrinter(&self.0.name))
67 .field("author", &IntoPrinter(&self.0.author))
68 .field(
69 "themes",
70 &VecPrinter(
71 &self
72 .0
73 .themes
74 .iter()
75 .map(|theme| UserThemePrinter(theme))
76 .collect(),
77 ),
78 )
79 .finish()
80 }
81}
82
83pub struct UserThemePrinter<'a>(&'a UserTheme);
84
85impl<'a> Debug for UserThemePrinter<'a> {
86 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
87 f.debug_struct("UserTheme")
88 .field("name", &IntoPrinter(&self.0.name))
89 .field("appearance", &AppearancePrinter(self.0.appearance))
90 .field("styles", &UserThemeStylesRefinementPrinter(&self.0.styles))
91 .finish()
92 }
93}
94
95pub struct AppearancePrinter(Appearance);
96
97impl Debug for AppearancePrinter {
98 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
99 write!(f, "Appearance::{:?}", self.0)
100 }
101}
102
103pub struct UserThemeStylesRefinementPrinter<'a>(&'a UserThemeStylesRefinement);
104
105impl<'a> Debug for UserThemeStylesRefinementPrinter<'a> {
106 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
107 f.debug_struct("UserThemeStylesRefinement")
108 .field("colors", &ThemeColorsRefinementPrinter(&self.0.colors))
109 .field("status", &StatusColorsRefinementPrinter(&self.0.status))
110 .field(
111 "syntax",
112 &OptionPrinter(
113 &self
114 .0
115 .syntax
116 .as_ref()
117 .map(|syntax| UserSyntaxThemePrinter(syntax)),
118 ),
119 )
120 .finish()
121 }
122}
123
124pub struct SystemColorsPrinter<'a>(&'a SystemColors);
125
126impl<'a> Debug for SystemColorsPrinter<'a> {
127 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
128 f.debug_struct("SystemColors")
129 .field("transparent", &HslaPrinter(self.0.transparent))
130 .field(
131 "mac_os_traffic_light_red",
132 &HslaPrinter(self.0.mac_os_traffic_light_red),
133 )
134 .field(
135 "mac_os_traffic_light_yellow",
136 &HslaPrinter(self.0.mac_os_traffic_light_yellow),
137 )
138 .field(
139 "mac_os_traffic_light_green",
140 &HslaPrinter(self.0.mac_os_traffic_light_green),
141 )
142 .finish()
143 }
144}
145
146pub struct ThemeColorsRefinementPrinter<'a>(&'a ThemeColorsRefinement);
147
148impl<'a> Debug for ThemeColorsRefinementPrinter<'a> {
149 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
150 let theme_colors = vec![
151 ("border", self.0.border),
152 ("border_variant", self.0.border_variant),
153 ("border_focused", self.0.border_focused),
154 ("border_selected", self.0.border_selected),
155 ("border_transparent", self.0.border_transparent),
156 ("border_disabled", self.0.border_disabled),
157 (
158 "elevated_surface_background",
159 self.0.elevated_surface_background,
160 ),
161 ("surface_background", self.0.surface_background),
162 ("background", self.0.background),
163 ("element_background", self.0.element_background),
164 ("element_hover", self.0.element_hover),
165 ("element_active", self.0.element_active),
166 ("element_selected", self.0.element_selected),
167 ("element_disabled", self.0.element_disabled),
168 ("drop_target_background", self.0.drop_target_background),
169 ("ghost_element_background", self.0.ghost_element_background),
170 ("ghost_element_hover", self.0.ghost_element_hover),
171 ("ghost_element_active", self.0.ghost_element_active),
172 ("ghost_element_selected", self.0.ghost_element_selected),
173 ("ghost_element_disabled", self.0.ghost_element_disabled),
174 ("text", self.0.text),
175 ("text_muted", self.0.text_muted),
176 ("text_placeholder", self.0.text_placeholder),
177 ("text_disabled", self.0.text_disabled),
178 ("text_accent", self.0.text_accent),
179 ("icon", self.0.icon),
180 ("icon_muted", self.0.icon_muted),
181 ("icon_disabled", self.0.icon_disabled),
182 ("icon_placeholder", self.0.icon_placeholder),
183 ("icon_accent", self.0.icon_accent),
184 ("status_bar_background", self.0.status_bar_background),
185 ("title_bar_background", self.0.title_bar_background),
186 ("toolbar_background", self.0.toolbar_background),
187 ("tab_bar_background", self.0.tab_bar_background),
188 ("tab_inactive_background", self.0.tab_inactive_background),
189 ("tab_active_background", self.0.tab_active_background),
190 (
191 "scrollbar_thumb_background",
192 self.0.scrollbar_thumb_background,
193 ),
194 (
195 "scrollbar_thumb_hover_background",
196 self.0.scrollbar_thumb_hover_background,
197 ),
198 ("scrollbar_thumb_border", self.0.scrollbar_thumb_border),
199 (
200 "scrollbar_track_background",
201 self.0.scrollbar_track_background,
202 ),
203 ("scrollbar_track_border", self.0.scrollbar_track_border),
204 ("editor_foreground", self.0.editor_foreground),
205 ("editor_background", self.0.editor_background),
206 ("editor_gutter_background", self.0.editor_gutter_background),
207 (
208 "editor_subheader_background",
209 self.0.editor_subheader_background,
210 ),
211 (
212 "editor_active_line_background",
213 self.0.editor_active_line_background,
214 ),
215 (
216 "editor_highlighted_line_background",
217 self.0.editor_highlighted_line_background,
218 ),
219 ("editor_line_number", self.0.editor_line_number),
220 (
221 "editor_active_line_number",
222 self.0.editor_active_line_number,
223 ),
224 ("editor_invisible", self.0.editor_invisible),
225 ("editor_wrap_guide", self.0.editor_wrap_guide),
226 ("editor_active_wrap_guide", self.0.editor_active_wrap_guide),
227 (
228 "editor_document_highlight_read_background",
229 self.0.editor_document_highlight_read_background,
230 ),
231 (
232 "editor_document_highlight_write_background",
233 self.0.editor_document_highlight_write_background,
234 ),
235 ("terminal_background", self.0.terminal_background),
236 (
237 "terminal_ansi_bright_black",
238 self.0.terminal_ansi_bright_black,
239 ),
240 ("terminal_ansi_bright_red", self.0.terminal_ansi_bright_red),
241 (
242 "terminal_ansi_bright_green",
243 self.0.terminal_ansi_bright_green,
244 ),
245 (
246 "terminal_ansi_bright_yellow",
247 self.0.terminal_ansi_bright_yellow,
248 ),
249 (
250 "terminal_ansi_bright_blue",
251 self.0.terminal_ansi_bright_blue,
252 ),
253 (
254 "terminal_ansi_bright_magenta",
255 self.0.terminal_ansi_bright_magenta,
256 ),
257 (
258 "terminal_ansi_bright_cyan",
259 self.0.terminal_ansi_bright_cyan,
260 ),
261 (
262 "terminal_ansi_bright_white",
263 self.0.terminal_ansi_bright_white,
264 ),
265 ("terminal_ansi_black", self.0.terminal_ansi_black),
266 ("terminal_ansi_red", self.0.terminal_ansi_red),
267 ("terminal_ansi_green", self.0.terminal_ansi_green),
268 ("terminal_ansi_yellow", self.0.terminal_ansi_yellow),
269 ("terminal_ansi_blue", self.0.terminal_ansi_blue),
270 ("terminal_ansi_magenta", self.0.terminal_ansi_magenta),
271 ("terminal_ansi_cyan", self.0.terminal_ansi_cyan),
272 ("terminal_ansi_white", self.0.terminal_ansi_white),
273 ];
274
275 f.write_str("ThemeColorsRefinement {")?;
276
277 for (color_name, color) in theme_colors {
278 if let Some(color) = color {
279 f.write_str(color_name)?;
280 f.write_str(": ")?;
281 f.write_str("Some(")?;
282 HslaPrinter(color).fmt(f)?;
283 f.write_str(")")?;
284 f.write_str(",")?;
285 } else {
286 log::warn!(target: "theme_printer", "No value for '{}' in theme", color_name);
287 }
288 }
289
290 f.write_str("..Default::default()")?;
291 f.write_str("}")
292 }
293}
294
295pub struct StatusColorsRefinementPrinter<'a>(&'a StatusColorsRefinement);
296
297impl<'a> Debug for StatusColorsRefinementPrinter<'a> {
298 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
299 let status_colors = vec![
300 ("conflict", self.0.conflict),
301 ("created", self.0.created),
302 ("deleted", self.0.deleted),
303 ("error", self.0.error),
304 ("hidden", self.0.hidden),
305 ("hint", self.0.hint),
306 ("ignored", self.0.ignored),
307 ("info", self.0.info),
308 ("modified", self.0.modified),
309 ("predictive", self.0.predictive),
310 ("renamed", self.0.renamed),
311 ("success", self.0.success),
312 ("unreachable", self.0.unreachable),
313 ("warning", self.0.warning),
314 ];
315
316 f.write_str("StatusColorsRefinement {")?;
317
318 for (color_name, color) in status_colors {
319 if let Some(color) = color {
320 f.write_str(color_name)?;
321 f.write_str(": ")?;
322 f.write_str("Some(")?;
323 HslaPrinter(color).fmt(f)?;
324 f.write_str(")")?;
325 f.write_str(",")?;
326 }
327 }
328
329 f.write_str("..Default::default()")?;
330 f.write_str("}")
331 }
332}
333
334pub struct PlayerColorsPrinter<'a>(&'a PlayerColors);
335
336impl<'a> Debug for PlayerColorsPrinter<'a> {
337 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
338 f.debug_tuple("PlayerColors")
339 .field(&VecPrinter(
340 &self
341 .0
342 .0
343 .iter()
344 .map(|player_color| PlayerColorPrinter(player_color))
345 .collect(),
346 ))
347 .finish()
348 }
349}
350
351pub struct PlayerColorPrinter<'a>(&'a PlayerColor);
352
353impl<'a> Debug for PlayerColorPrinter<'a> {
354 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
355 f.debug_struct("PlayerColor")
356 .field("cursor", &HslaPrinter(self.0.cursor))
357 .field("background", &HslaPrinter(self.0.background))
358 .field("selection", &HslaPrinter(self.0.selection))
359 .finish()
360 }
361}
362
363pub struct UserSyntaxThemePrinter<'a>(&'a UserSyntaxTheme);
364
365impl<'a> Debug for UserSyntaxThemePrinter<'a> {
366 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
367 f.debug_struct("UserSyntaxTheme")
368 .field(
369 "highlights",
370 &VecPrinter(
371 &self
372 .0
373 .highlights
374 .iter()
375 .map(|(token, highlight)| {
376 (IntoPrinter(token), UserHighlightStylePrinter(&highlight))
377 })
378 .collect(),
379 ),
380 )
381 .finish()
382 }
383}
384
385pub struct UserHighlightStylePrinter<'a>(&'a UserHighlightStyle);
386
387impl<'a> Debug for UserHighlightStylePrinter<'a> {
388 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
389 f.write_str("UserHighlightStyle {")?;
390
391 if let Some(color) = self.0.color {
392 f.write_str("color")?;
393 f.write_str(": ")?;
394 f.write_str("Some(")?;
395 HslaPrinter(color).fmt(f)?;
396 f.write_str(")")?;
397 f.write_str(",")?;
398 }
399
400 if let Some(font_style) = self.0.font_style {
401 f.write_str("font_style")?;
402 f.write_str(": ")?;
403 f.write_str("Some(")?;
404 write!(f, "UserFontStyle::{:?}", font_style)?;
405 f.write_str(")")?;
406 f.write_str(",")?;
407 }
408
409 if let Some(font_weight) = self.0.font_weight.as_ref() {
410 f.write_str("font_weight")?;
411 f.write_str(": ")?;
412 f.write_str("Some(")?;
413 write!(f, "UserFontWeight({:?})", font_weight.0)?;
414 f.write_str(")")?;
415 f.write_str(",")?;
416 }
417
418 f.write_str("..Default::default()")?;
419 f.write_str("}")
420 }
421}