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 (
248 "terminal_ansi_bright_black",
249 self.0.terminal_ansi_bright_black,
250 ),
251 ("terminal_ansi_bright_red", self.0.terminal_ansi_bright_red),
252 (
253 "terminal_ansi_bright_green",
254 self.0.terminal_ansi_bright_green,
255 ),
256 (
257 "terminal_ansi_bright_yellow",
258 self.0.terminal_ansi_bright_yellow,
259 ),
260 (
261 "terminal_ansi_bright_blue",
262 self.0.terminal_ansi_bright_blue,
263 ),
264 (
265 "terminal_ansi_bright_magenta",
266 self.0.terminal_ansi_bright_magenta,
267 ),
268 (
269 "terminal_ansi_bright_cyan",
270 self.0.terminal_ansi_bright_cyan,
271 ),
272 (
273 "terminal_ansi_bright_white",
274 self.0.terminal_ansi_bright_white,
275 ),
276 ("terminal_ansi_black", self.0.terminal_ansi_black),
277 ("terminal_ansi_red", self.0.terminal_ansi_red),
278 ("terminal_ansi_green", self.0.terminal_ansi_green),
279 ("terminal_ansi_yellow", self.0.terminal_ansi_yellow),
280 ("terminal_ansi_blue", self.0.terminal_ansi_blue),
281 ("terminal_ansi_magenta", self.0.terminal_ansi_magenta),
282 ("terminal_ansi_cyan", self.0.terminal_ansi_cyan),
283 ("terminal_ansi_white", self.0.terminal_ansi_white),
284 ("link_text_hover", self.0.link_text_hover),
285 ];
286
287 f.write_str("ThemeColorsRefinement {")?;
288
289 for (color_name, color) in theme_colors {
290 if let Some(color) = color {
291 f.write_str(color_name)?;
292 f.write_str(": ")?;
293 f.write_str("Some(")?;
294 HslaPrinter(color).fmt(f)?;
295 f.write_str(")")?;
296 f.write_str(",")?;
297 } else {
298 log::warn!(target: "theme_printer", "No value for '{}' in theme", color_name);
299 }
300 }
301
302 f.write_str("..Default::default()")?;
303 f.write_str("}")
304 }
305}
306
307pub struct StatusColorsRefinementPrinter<'a>(&'a StatusColorsRefinement);
308
309impl<'a> Debug for StatusColorsRefinementPrinter<'a> {
310 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
311 let status_colors = vec![
312 ("conflict", self.0.conflict),
313 ("conflict_background", self.0.conflict_background),
314 ("conflict_border", self.0.conflict_border),
315 ("created", self.0.created),
316 ("created_background", self.0.created_background),
317 ("created_border", self.0.created_border),
318 ("deleted", self.0.deleted),
319 ("deleted_background", self.0.deleted_background),
320 ("deleted_border", self.0.deleted_border),
321 ("error", self.0.error),
322 ("error_background", self.0.error_background),
323 ("error_border", self.0.error_border),
324 ("hidden", self.0.hidden),
325 ("hidden_background", self.0.hidden_background),
326 ("hidden_border", self.0.hidden_border),
327 ("hint", self.0.hint),
328 ("hint_background", self.0.hint_background),
329 ("hint_border", self.0.hint_border),
330 ("ignored", self.0.ignored),
331 ("ignored_background", self.0.ignored_background),
332 ("ignored_border", self.0.ignored_border),
333 ("info", self.0.info),
334 ("info_background", self.0.info_background),
335 ("info_border", self.0.info_border),
336 ("modified", self.0.modified),
337 ("modified_background", self.0.modified_background),
338 ("modified_border", self.0.modified_border),
339 ("predictive", self.0.predictive),
340 ("predictive_background", self.0.predictive_background),
341 ("predictive_border", self.0.predictive_border),
342 ("renamed", self.0.renamed),
343 ("renamed_background", self.0.renamed_background),
344 ("renamed_border", self.0.renamed_border),
345 ("success", self.0.success),
346 ("success_background", self.0.success_background),
347 ("success_border", self.0.success_border),
348 ("unreachable", self.0.unreachable),
349 ("unreachable_background", self.0.unreachable_background),
350 ("unreachable_border", self.0.unreachable_border),
351 ("warning", self.0.warning),
352 ("warning_background", self.0.warning_background),
353 ("warning_border", self.0.warning_border),
354 ];
355
356 f.write_str("StatusColorsRefinement {")?;
357
358 for (color_name, color) in status_colors {
359 if let Some(color) = color {
360 f.write_str(color_name)?;
361 f.write_str(": ")?;
362 f.write_str("Some(")?;
363 HslaPrinter(color).fmt(f)?;
364 f.write_str(")")?;
365 f.write_str(",")?;
366 }
367 }
368
369 f.write_str("..Default::default()")?;
370 f.write_str("}")
371 }
372}
373
374pub struct PlayerColorsPrinter<'a>(&'a PlayerColors);
375
376impl<'a> Debug for PlayerColorsPrinter<'a> {
377 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
378 f.debug_tuple("PlayerColors")
379 .field(&VecPrinter(
380 &self
381 .0
382 .0
383 .iter()
384 .map(|player_color| PlayerColorPrinter(player_color))
385 .collect(),
386 ))
387 .finish()
388 }
389}
390
391pub struct PlayerColorPrinter<'a>(&'a PlayerColor);
392
393impl<'a> Debug for PlayerColorPrinter<'a> {
394 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
395 f.debug_struct("PlayerColor")
396 .field("cursor", &HslaPrinter(self.0.cursor))
397 .field("background", &HslaPrinter(self.0.background))
398 .field("selection", &HslaPrinter(self.0.selection))
399 .finish()
400 }
401}
402
403pub struct UserSyntaxThemePrinter<'a>(&'a UserSyntaxTheme);
404
405impl<'a> Debug for UserSyntaxThemePrinter<'a> {
406 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
407 f.debug_struct("UserSyntaxTheme")
408 .field(
409 "highlights",
410 &VecPrinter(
411 &self
412 .0
413 .highlights
414 .iter()
415 .map(|(token, highlight)| {
416 (IntoPrinter(token), UserHighlightStylePrinter(&highlight))
417 })
418 .collect(),
419 ),
420 )
421 .finish()
422 }
423}
424
425pub struct UserHighlightStylePrinter<'a>(&'a UserHighlightStyle);
426
427impl<'a> Debug for UserHighlightStylePrinter<'a> {
428 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
429 f.write_str("UserHighlightStyle {")?;
430
431 if let Some(color) = self.0.color {
432 f.write_str("color")?;
433 f.write_str(": ")?;
434 f.write_str("Some(")?;
435 HslaPrinter(color).fmt(f)?;
436 f.write_str(")")?;
437 f.write_str(",")?;
438 }
439
440 if let Some(font_style) = self.0.font_style {
441 f.write_str("font_style")?;
442 f.write_str(": ")?;
443 f.write_str("Some(")?;
444 write!(f, "UserFontStyle::{:?}", font_style)?;
445 f.write_str(")")?;
446 f.write_str(",")?;
447 }
448
449 if let Some(font_weight) = self.0.font_weight.as_ref() {
450 f.write_str("font_weight")?;
451 f.write_str(": ")?;
452 f.write_str("Some(")?;
453 write!(f, "UserFontWeight({:?})", font_weight.0)?;
454 f.write_str(")")?;
455 f.write_str(",")?;
456 }
457
458 f.write_str("..Default::default()")?;
459 f.write_str("}")
460 }
461}