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 ("created", self.0.created),
314 ("deleted", self.0.deleted),
315 ("error", self.0.error),
316 ("hidden", self.0.hidden),
317 ("hint", self.0.hint),
318 ("ignored", self.0.ignored),
319 ("info", self.0.info),
320 ("modified", self.0.modified),
321 ("predictive", self.0.predictive),
322 ("renamed", self.0.renamed),
323 ("success", self.0.success),
324 ("unreachable", self.0.unreachable),
325 ("warning", self.0.warning),
326 ];
327
328 f.write_str("StatusColorsRefinement {")?;
329
330 for (color_name, color) in status_colors {
331 if let Some(color) = color {
332 f.write_str(color_name)?;
333 f.write_str(": ")?;
334 f.write_str("Some(")?;
335 HslaPrinter(color).fmt(f)?;
336 f.write_str(")")?;
337 f.write_str(",")?;
338 }
339 }
340
341 f.write_str("..Default::default()")?;
342 f.write_str("}")
343 }
344}
345
346pub struct PlayerColorsPrinter<'a>(&'a PlayerColors);
347
348impl<'a> Debug for PlayerColorsPrinter<'a> {
349 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
350 f.debug_tuple("PlayerColors")
351 .field(&VecPrinter(
352 &self
353 .0
354 .0
355 .iter()
356 .map(|player_color| PlayerColorPrinter(player_color))
357 .collect(),
358 ))
359 .finish()
360 }
361}
362
363pub struct PlayerColorPrinter<'a>(&'a PlayerColor);
364
365impl<'a> Debug for PlayerColorPrinter<'a> {
366 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
367 f.debug_struct("PlayerColor")
368 .field("cursor", &HslaPrinter(self.0.cursor))
369 .field("background", &HslaPrinter(self.0.background))
370 .field("selection", &HslaPrinter(self.0.selection))
371 .finish()
372 }
373}
374
375pub struct UserSyntaxThemePrinter<'a>(&'a UserSyntaxTheme);
376
377impl<'a> Debug for UserSyntaxThemePrinter<'a> {
378 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
379 f.debug_struct("UserSyntaxTheme")
380 .field(
381 "highlights",
382 &VecPrinter(
383 &self
384 .0
385 .highlights
386 .iter()
387 .map(|(token, highlight)| {
388 (IntoPrinter(token), UserHighlightStylePrinter(&highlight))
389 })
390 .collect(),
391 ),
392 )
393 .finish()
394 }
395}
396
397pub struct UserHighlightStylePrinter<'a>(&'a UserHighlightStyle);
398
399impl<'a> Debug for UserHighlightStylePrinter<'a> {
400 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
401 f.write_str("UserHighlightStyle {")?;
402
403 if let Some(color) = self.0.color {
404 f.write_str("color")?;
405 f.write_str(": ")?;
406 f.write_str("Some(")?;
407 HslaPrinter(color).fmt(f)?;
408 f.write_str(")")?;
409 f.write_str(",")?;
410 }
411
412 if let Some(font_style) = self.0.font_style {
413 f.write_str("font_style")?;
414 f.write_str(": ")?;
415 f.write_str("Some(")?;
416 write!(f, "UserFontStyle::{:?}", font_style)?;
417 f.write_str(")")?;
418 f.write_str(",")?;
419 }
420
421 if let Some(font_weight) = self.0.font_weight.as_ref() {
422 f.write_str("font_weight")?;
423 f.write_str(": ")?;
424 f.write_str("Some(")?;
425 write!(f, "UserFontWeight({:?})", font_weight.0)?;
426 f.write_str(")")?;
427 f.write_str(",")?;
428 }
429
430 f.write_str("..Default::default()")?;
431 f.write_str("}")
432 }
433}