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 "player",
112 &OptionPrinter(
113 &self
114 .0
115 .player
116 .as_ref()
117 .map(|player_colors| PlayerColorsPrinter(player_colors)),
118 ),
119 )
120 .field(
121 "syntax",
122 &OptionPrinter(
123 &self
124 .0
125 .syntax
126 .as_ref()
127 .map(|syntax| UserSyntaxThemePrinter(syntax)),
128 ),
129 )
130 .finish()
131 }
132}
133
134pub struct SystemColorsPrinter<'a>(&'a SystemColors);
135
136impl<'a> Debug for SystemColorsPrinter<'a> {
137 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
138 f.debug_struct("SystemColors")
139 .field("transparent", &HslaPrinter(self.0.transparent))
140 .field(
141 "mac_os_traffic_light_red",
142 &HslaPrinter(self.0.mac_os_traffic_light_red),
143 )
144 .field(
145 "mac_os_traffic_light_yellow",
146 &HslaPrinter(self.0.mac_os_traffic_light_yellow),
147 )
148 .field(
149 "mac_os_traffic_light_green",
150 &HslaPrinter(self.0.mac_os_traffic_light_green),
151 )
152 .finish()
153 }
154}
155
156pub struct ThemeColorsRefinementPrinter<'a>(&'a ThemeColorsRefinement);
157
158impl<'a> Debug for ThemeColorsRefinementPrinter<'a> {
159 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
160 let theme_colors = vec![
161 ("border", self.0.border),
162 ("border_variant", self.0.border_variant),
163 ("border_focused", self.0.border_focused),
164 ("border_selected", self.0.border_selected),
165 ("border_transparent", self.0.border_transparent),
166 ("border_disabled", self.0.border_disabled),
167 (
168 "elevated_surface_background",
169 self.0.elevated_surface_background,
170 ),
171 ("surface_background", self.0.surface_background),
172 ("background", self.0.background),
173 ("panel_background", self.0.panel_background),
174 ("element_background", self.0.element_background),
175 ("element_hover", self.0.element_hover),
176 ("element_active", self.0.element_active),
177 ("element_selected", self.0.element_selected),
178 ("element_disabled", self.0.element_disabled),
179 ("drop_target_background", self.0.drop_target_background),
180 ("ghost_element_background", self.0.ghost_element_background),
181 ("ghost_element_hover", self.0.ghost_element_hover),
182 ("ghost_element_active", self.0.ghost_element_active),
183 ("ghost_element_selected", self.0.ghost_element_selected),
184 ("ghost_element_disabled", self.0.ghost_element_disabled),
185 ("text", self.0.text),
186 ("text_muted", self.0.text_muted),
187 ("text_placeholder", self.0.text_placeholder),
188 ("text_disabled", self.0.text_disabled),
189 ("text_accent", self.0.text_accent),
190 ("icon", self.0.icon),
191 ("icon_muted", self.0.icon_muted),
192 ("icon_disabled", self.0.icon_disabled),
193 ("icon_placeholder", self.0.icon_placeholder),
194 ("icon_accent", self.0.icon_accent),
195 ("status_bar_background", self.0.status_bar_background),
196 ("title_bar_background", self.0.title_bar_background),
197 ("toolbar_background", self.0.toolbar_background),
198 ("tab_bar_background", self.0.tab_bar_background),
199 ("tab_inactive_background", self.0.tab_inactive_background),
200 ("tab_active_background", self.0.tab_active_background),
201 (
202 "scrollbar_thumb_background",
203 self.0.scrollbar_thumb_background,
204 ),
205 (
206 "scrollbar_thumb_hover_background",
207 self.0.scrollbar_thumb_hover_background,
208 ),
209 ("scrollbar_thumb_border", self.0.scrollbar_thumb_border),
210 (
211 "scrollbar_track_background",
212 self.0.scrollbar_track_background,
213 ),
214 ("scrollbar_track_border", self.0.scrollbar_track_border),
215 ("editor_foreground", self.0.editor_foreground),
216 ("editor_background", self.0.editor_background),
217 ("editor_gutter_background", self.0.editor_gutter_background),
218 (
219 "editor_subheader_background",
220 self.0.editor_subheader_background,
221 ),
222 (
223 "editor_active_line_background",
224 self.0.editor_active_line_background,
225 ),
226 (
227 "editor_highlighted_line_background",
228 self.0.editor_highlighted_line_background,
229 ),
230 ("editor_line_number", self.0.editor_line_number),
231 (
232 "editor_active_line_number",
233 self.0.editor_active_line_number,
234 ),
235 ("editor_invisible", self.0.editor_invisible),
236 ("editor_wrap_guide", self.0.editor_wrap_guide),
237 ("editor_active_wrap_guide", self.0.editor_active_wrap_guide),
238 (
239 "editor_document_highlight_read_background",
240 self.0.editor_document_highlight_read_background,
241 ),
242 (
243 "editor_document_highlight_write_background",
244 self.0.editor_document_highlight_write_background,
245 ),
246 ("terminal_background", self.0.terminal_background),
247 ("terminal_foreground", self.0.terminal_foreground),
248 (
249 "terminal_bright_foreground",
250 self.0.terminal_bright_foreground,
251 ),
252 ("terminal_dim_foreground", self.0.terminal_dim_foreground),
253 ("terminal_ansi_black", self.0.terminal_ansi_black),
254 (
255 "terminal_ansi_bright_black",
256 self.0.terminal_ansi_bright_black,
257 ),
258 ("terminal_ansi_dim_black", self.0.terminal_ansi_dim_black),
259 ("terminal_ansi_red", self.0.terminal_ansi_red),
260 ("terminal_ansi_bright_red", self.0.terminal_ansi_bright_red),
261 ("terminal_ansi_dim_red", self.0.terminal_ansi_dim_red),
262 ("terminal_ansi_green", self.0.terminal_ansi_green),
263 (
264 "terminal_ansi_bright_green",
265 self.0.terminal_ansi_bright_green,
266 ),
267 ("terminal_ansi_dim_green", self.0.terminal_ansi_dim_green),
268 ("terminal_ansi_yellow", self.0.terminal_ansi_yellow),
269 (
270 "terminal_ansi_bright_yellow",
271 self.0.terminal_ansi_bright_yellow,
272 ),
273 ("terminal_ansi_dim_yellow", self.0.terminal_ansi_dim_yellow),
274 ("terminal_ansi_blue", self.0.terminal_ansi_blue),
275 (
276 "terminal_ansi_bright_blue",
277 self.0.terminal_ansi_bright_blue,
278 ),
279 ("terminal_ansi_dim_blue", self.0.terminal_ansi_dim_blue),
280 ("terminal_ansi_magenta", self.0.terminal_ansi_magenta),
281 (
282 "terminal_ansi_bright_magenta",
283 self.0.terminal_ansi_bright_magenta,
284 ),
285 (
286 "terminal_ansi_dim_magenta",
287 self.0.terminal_ansi_dim_magenta,
288 ),
289 ("terminal_ansi_cyan", self.0.terminal_ansi_cyan),
290 (
291 "terminal_ansi_bright_cyan",
292 self.0.terminal_ansi_bright_cyan,
293 ),
294 ("terminal_ansi_dim_cyan", self.0.terminal_ansi_dim_cyan),
295 ("terminal_ansi_white", self.0.terminal_ansi_white),
296 (
297 "terminal_ansi_bright_white",
298 self.0.terminal_ansi_bright_white,
299 ),
300 ("terminal_ansi_dim_white", self.0.terminal_ansi_dim_white),
301 ("link_text_hover", self.0.link_text_hover),
302 ];
303
304 f.write_str("ThemeColorsRefinement {")?;
305
306 for (color_name, color) in theme_colors {
307 if let Some(color) = color {
308 f.write_str(color_name)?;
309 f.write_str(": ")?;
310 f.write_str("Some(")?;
311 HslaPrinter(color).fmt(f)?;
312 f.write_str(")")?;
313 f.write_str(",")?;
314 } else {
315 log::warn!(target: "theme_printer", "No value for '{}' in theme", color_name);
316 }
317 }
318
319 f.write_str("..Default::default()")?;
320 f.write_str("}")
321 }
322}
323
324pub struct StatusColorsRefinementPrinter<'a>(&'a StatusColorsRefinement);
325
326impl<'a> Debug for StatusColorsRefinementPrinter<'a> {
327 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
328 let status_colors = vec![
329 ("conflict", self.0.conflict),
330 ("conflict_background", self.0.conflict_background),
331 ("conflict_border", self.0.conflict_border),
332 ("created", self.0.created),
333 ("created_background", self.0.created_background),
334 ("created_border", self.0.created_border),
335 ("deleted", self.0.deleted),
336 ("deleted_background", self.0.deleted_background),
337 ("deleted_border", self.0.deleted_border),
338 ("error", self.0.error),
339 ("error_background", self.0.error_background),
340 ("error_border", self.0.error_border),
341 ("hidden", self.0.hidden),
342 ("hidden_background", self.0.hidden_background),
343 ("hidden_border", self.0.hidden_border),
344 ("hint", self.0.hint),
345 ("hint_background", self.0.hint_background),
346 ("hint_border", self.0.hint_border),
347 ("ignored", self.0.ignored),
348 ("ignored_background", self.0.ignored_background),
349 ("ignored_border", self.0.ignored_border),
350 ("info", self.0.info),
351 ("info_background", self.0.info_background),
352 ("info_border", self.0.info_border),
353 ("modified", self.0.modified),
354 ("modified_background", self.0.modified_background),
355 ("modified_border", self.0.modified_border),
356 ("predictive", self.0.predictive),
357 ("predictive_background", self.0.predictive_background),
358 ("predictive_border", self.0.predictive_border),
359 ("renamed", self.0.renamed),
360 ("renamed_background", self.0.renamed_background),
361 ("renamed_border", self.0.renamed_border),
362 ("success", self.0.success),
363 ("success_background", self.0.success_background),
364 ("success_border", self.0.success_border),
365 ("unreachable", self.0.unreachable),
366 ("unreachable_background", self.0.unreachable_background),
367 ("unreachable_border", self.0.unreachable_border),
368 ("warning", self.0.warning),
369 ("warning_background", self.0.warning_background),
370 ("warning_border", self.0.warning_border),
371 ];
372
373 f.write_str("StatusColorsRefinement {")?;
374
375 for (color_name, color) in status_colors {
376 if let Some(color) = color {
377 f.write_str(color_name)?;
378 f.write_str(": ")?;
379 f.write_str("Some(")?;
380 HslaPrinter(color).fmt(f)?;
381 f.write_str(")")?;
382 f.write_str(",")?;
383 }
384 }
385
386 f.write_str("..Default::default()")?;
387 f.write_str("}")
388 }
389}
390
391pub struct PlayerColorsPrinter<'a>(&'a PlayerColors);
392
393impl<'a> Debug for PlayerColorsPrinter<'a> {
394 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
395 f.debug_tuple("PlayerColors")
396 .field(&VecPrinter(
397 &self
398 .0
399 .0
400 .iter()
401 .map(|player_color| PlayerColorPrinter(player_color))
402 .collect(),
403 ))
404 .finish()
405 }
406}
407
408pub struct PlayerColorPrinter<'a>(&'a PlayerColor);
409
410impl<'a> Debug for PlayerColorPrinter<'a> {
411 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
412 f.debug_struct("PlayerColor")
413 .field("cursor", &HslaPrinter(self.0.cursor))
414 .field("background", &HslaPrinter(self.0.background))
415 .field("selection", &HslaPrinter(self.0.selection))
416 .finish()
417 }
418}
419
420pub struct UserSyntaxThemePrinter<'a>(&'a UserSyntaxTheme);
421
422impl<'a> Debug for UserSyntaxThemePrinter<'a> {
423 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
424 f.debug_struct("UserSyntaxTheme")
425 .field(
426 "highlights",
427 &VecPrinter(
428 &self
429 .0
430 .highlights
431 .iter()
432 .map(|(token, highlight)| {
433 (IntoPrinter(token), UserHighlightStylePrinter(&highlight))
434 })
435 .collect(),
436 ),
437 )
438 .finish()
439 }
440}
441
442pub struct UserHighlightStylePrinter<'a>(&'a UserHighlightStyle);
443
444impl<'a> Debug for UserHighlightStylePrinter<'a> {
445 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
446 f.write_str("UserHighlightStyle {")?;
447
448 if let Some(color) = self.0.color {
449 f.write_str("color")?;
450 f.write_str(": ")?;
451 f.write_str("Some(")?;
452 HslaPrinter(color).fmt(f)?;
453 f.write_str(")")?;
454 f.write_str(",")?;
455 }
456
457 if let Some(font_style) = self.0.font_style {
458 f.write_str("font_style")?;
459 f.write_str(": ")?;
460 f.write_str("Some(")?;
461 write!(f, "UserFontStyle::{:?}", font_style)?;
462 f.write_str(")")?;
463 f.write_str(",")?;
464 }
465
466 if let Some(font_weight) = self.0.font_weight.as_ref() {
467 f.write_str("font_weight")?;
468 f.write_str(": ")?;
469 f.write_str("Some(")?;
470 write!(f, "UserFontWeight({:?})", font_weight.0)?;
471 f.write_str(")")?;
472 f.write_str(",")?;
473 }
474
475 f.write_str("..Default::default()")?;
476 f.write_str("}")
477 }
478}