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