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 ("headline", self.0.headline),
285 ("paragraph", self.0.paragraph),
286 ("link_text", self.0.link_text),
287 ("link_text_hover", self.0.link_text_hover),
288 ("link_uri", self.0.link_uri),
289 ("inline_code_background", self.0.inline_code_background),
290 ("inline_code_border", self.0.inline_code_border),
291 ("code_block_background", self.0.code_block_background),
292 ("code_block_border", self.0.code_block_border),
293 ("emphasis", self.0.emphasis),
294 ];
295
296 f.write_str("ThemeColorsRefinement {")?;
297
298 for (color_name, color) in theme_colors {
299 if let Some(color) = color {
300 f.write_str(color_name)?;
301 f.write_str(": ")?;
302 f.write_str("Some(")?;
303 HslaPrinter(color).fmt(f)?;
304 f.write_str(")")?;
305 f.write_str(",")?;
306 } else {
307 log::warn!(target: "theme_printer", "No value for '{}' in theme", color_name);
308 }
309 }
310
311 f.write_str("..Default::default()")?;
312 f.write_str("}")
313 }
314}
315
316pub struct StatusColorsRefinementPrinter<'a>(&'a StatusColorsRefinement);
317
318impl<'a> Debug for StatusColorsRefinementPrinter<'a> {
319 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
320 let status_colors = vec![
321 ("conflict", self.0.conflict),
322 ("created", self.0.created),
323 ("deleted", self.0.deleted),
324 ("error", self.0.error),
325 ("hidden", self.0.hidden),
326 ("hint", self.0.hint),
327 ("ignored", self.0.ignored),
328 ("info", self.0.info),
329 ("modified", self.0.modified),
330 ("predictive", self.0.predictive),
331 ("renamed", self.0.renamed),
332 ("success", self.0.success),
333 ("unreachable", self.0.unreachable),
334 ("warning", self.0.warning),
335 ];
336
337 f.write_str("StatusColorsRefinement {")?;
338
339 for (color_name, color) in status_colors {
340 if let Some(color) = color {
341 f.write_str(color_name)?;
342 f.write_str(": ")?;
343 f.write_str("Some(")?;
344 HslaPrinter(color).fmt(f)?;
345 f.write_str(")")?;
346 f.write_str(",")?;
347 }
348 }
349
350 f.write_str("..Default::default()")?;
351 f.write_str("}")
352 }
353}
354
355pub struct PlayerColorsPrinter<'a>(&'a PlayerColors);
356
357impl<'a> Debug for PlayerColorsPrinter<'a> {
358 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
359 f.debug_tuple("PlayerColors")
360 .field(&VecPrinter(
361 &self
362 .0
363 .0
364 .iter()
365 .map(|player_color| PlayerColorPrinter(player_color))
366 .collect(),
367 ))
368 .finish()
369 }
370}
371
372pub struct PlayerColorPrinter<'a>(&'a PlayerColor);
373
374impl<'a> Debug for PlayerColorPrinter<'a> {
375 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
376 f.debug_struct("PlayerColor")
377 .field("cursor", &HslaPrinter(self.0.cursor))
378 .field("background", &HslaPrinter(self.0.background))
379 .field("selection", &HslaPrinter(self.0.selection))
380 .finish()
381 }
382}
383
384pub struct UserSyntaxThemePrinter<'a>(&'a UserSyntaxTheme);
385
386impl<'a> Debug for UserSyntaxThemePrinter<'a> {
387 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
388 f.debug_struct("UserSyntaxTheme")
389 .field(
390 "highlights",
391 &VecPrinter(
392 &self
393 .0
394 .highlights
395 .iter()
396 .map(|(token, highlight)| {
397 (IntoPrinter(token), UserHighlightStylePrinter(&highlight))
398 })
399 .collect(),
400 ),
401 )
402 .finish()
403 }
404}
405
406pub struct UserHighlightStylePrinter<'a>(&'a UserHighlightStyle);
407
408impl<'a> Debug for UserHighlightStylePrinter<'a> {
409 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
410 f.write_str("UserHighlightStyle {")?;
411
412 if let Some(color) = self.0.color {
413 f.write_str("color")?;
414 f.write_str(": ")?;
415 f.write_str("Some(")?;
416 HslaPrinter(color).fmt(f)?;
417 f.write_str(")")?;
418 f.write_str(",")?;
419 }
420
421 if let Some(font_style) = self.0.font_style {
422 f.write_str("font_style")?;
423 f.write_str(": ")?;
424 f.write_str("Some(")?;
425 write!(f, "UserFontStyle::{:?}", font_style)?;
426 f.write_str(")")?;
427 f.write_str(",")?;
428 }
429
430 if let Some(font_weight) = self.0.font_weight.as_ref() {
431 f.write_str("font_weight")?;
432 f.write_str(": ")?;
433 f.write_str("Some(")?;
434 write!(f, "UserFontWeight({:?})", font_weight.0)?;
435 f.write_str(")")?;
436 f.write_str(",")?;
437 }
438
439 f.write_str("..Default::default()")?;
440 f.write_str("}")
441 }
442}