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_background", self.0.editor_background),
205 ("editor_gutter_background", self.0.editor_gutter_background),
206 (
207 "editor_subheader_background",
208 self.0.editor_subheader_background,
209 ),
210 (
211 "editor_active_line_background",
212 self.0.editor_active_line_background,
213 ),
214 (
215 "editor_highlighted_line_background",
216 self.0.editor_highlighted_line_background,
217 ),
218 ("editor_line_number", self.0.editor_line_number),
219 (
220 "editor_active_line_number",
221 self.0.editor_active_line_number,
222 ),
223 ("editor_invisible", self.0.editor_invisible),
224 ("editor_wrap_guide", self.0.editor_wrap_guide),
225 ("editor_active_wrap_guide", self.0.editor_active_wrap_guide),
226 (
227 "editor_document_highlight_read_background",
228 self.0.editor_document_highlight_read_background,
229 ),
230 (
231 "editor_document_highlight_write_background",
232 self.0.editor_document_highlight_write_background,
233 ),
234 ("terminal_background", self.0.terminal_background),
235 (
236 "terminal_ansi_bright_black",
237 self.0.terminal_ansi_bright_black,
238 ),
239 ("terminal_ansi_bright_red", self.0.terminal_ansi_bright_red),
240 (
241 "terminal_ansi_bright_green",
242 self.0.terminal_ansi_bright_green,
243 ),
244 (
245 "terminal_ansi_bright_yellow",
246 self.0.terminal_ansi_bright_yellow,
247 ),
248 (
249 "terminal_ansi_bright_blue",
250 self.0.terminal_ansi_bright_blue,
251 ),
252 (
253 "terminal_ansi_bright_magenta",
254 self.0.terminal_ansi_bright_magenta,
255 ),
256 (
257 "terminal_ansi_bright_cyan",
258 self.0.terminal_ansi_bright_cyan,
259 ),
260 (
261 "terminal_ansi_bright_white",
262 self.0.terminal_ansi_bright_white,
263 ),
264 ("terminal_ansi_black", self.0.terminal_ansi_black),
265 ("terminal_ansi_red", self.0.terminal_ansi_red),
266 ("terminal_ansi_green", self.0.terminal_ansi_green),
267 ("terminal_ansi_yellow", self.0.terminal_ansi_yellow),
268 ("terminal_ansi_blue", self.0.terminal_ansi_blue),
269 ("terminal_ansi_magenta", self.0.terminal_ansi_magenta),
270 ("terminal_ansi_cyan", self.0.terminal_ansi_cyan),
271 ("terminal_ansi_white", self.0.terminal_ansi_white),
272 ];
273
274 f.write_str("ThemeColorsRefinement {")?;
275
276 for (color_name, color) in theme_colors {
277 if let Some(color) = color {
278 f.write_str(color_name)?;
279 f.write_str(": ")?;
280 f.write_str("Some(")?;
281 HslaPrinter(color).fmt(f)?;
282 f.write_str(")")?;
283 f.write_str(",")?;
284 }
285 }
286
287 f.write_str("..Default::default()")?;
288 f.write_str("}")
289 }
290}
291
292pub struct StatusColorsRefinementPrinter<'a>(&'a StatusColorsRefinement);
293
294impl<'a> Debug for StatusColorsRefinementPrinter<'a> {
295 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
296 let status_colors = vec![
297 ("conflict", self.0.conflict),
298 ("created", self.0.created),
299 ("deleted", self.0.deleted),
300 ("error", self.0.error),
301 ("hidden", self.0.hidden),
302 ("hint", self.0.hint),
303 ("ignored", self.0.ignored),
304 ("info", self.0.info),
305 ("modified", self.0.modified),
306 ("predictive", self.0.predictive),
307 ("renamed", self.0.renamed),
308 ("success", self.0.success),
309 ("unreachable", self.0.unreachable),
310 ("warning", self.0.warning),
311 ];
312
313 f.write_str("StatusColorsRefinement {")?;
314
315 for (color_name, color) in status_colors {
316 if let Some(color) = color {
317 f.write_str(color_name)?;
318 f.write_str(": ")?;
319 f.write_str("Some(")?;
320 HslaPrinter(color).fmt(f)?;
321 f.write_str(")")?;
322 f.write_str(",")?;
323 }
324 }
325
326 f.write_str("..Default::default()")?;
327 f.write_str("}")
328 }
329}
330
331pub struct PlayerColorsPrinter<'a>(&'a PlayerColors);
332
333impl<'a> Debug for PlayerColorsPrinter<'a> {
334 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
335 f.debug_tuple("PlayerColors")
336 .field(&VecPrinter(
337 &self
338 .0
339 .0
340 .iter()
341 .map(|player_color| PlayerColorPrinter(player_color))
342 .collect(),
343 ))
344 .finish()
345 }
346}
347
348pub struct PlayerColorPrinter<'a>(&'a PlayerColor);
349
350impl<'a> Debug for PlayerColorPrinter<'a> {
351 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
352 f.debug_struct("PlayerColor")
353 .field("cursor", &HslaPrinter(self.0.cursor))
354 .field("background", &HslaPrinter(self.0.background))
355 .field("selection", &HslaPrinter(self.0.selection))
356 .finish()
357 }
358}
359
360pub struct UserSyntaxThemePrinter<'a>(&'a UserSyntaxTheme);
361
362impl<'a> Debug for UserSyntaxThemePrinter<'a> {
363 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
364 f.debug_struct("UserSyntaxTheme")
365 .field(
366 "highlights",
367 &VecPrinter(
368 &self
369 .0
370 .highlights
371 .iter()
372 .map(|(token, highlight)| {
373 (IntoPrinter(token), UserHighlightStylePrinter(&highlight))
374 })
375 .collect(),
376 ),
377 )
378 .finish()
379 }
380}
381
382pub struct UserHighlightStylePrinter<'a>(&'a UserHighlightStyle);
383
384impl<'a> Debug for UserHighlightStylePrinter<'a> {
385 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
386 f.write_str("UserHighlightStyle {")?;
387
388 if let Some(color) = self.0.color {
389 f.write_str("color")?;
390 f.write_str(": ")?;
391 f.write_str("Some(")?;
392 HslaPrinter(color).fmt(f)?;
393 f.write_str(")")?;
394 f.write_str(",")?;
395 }
396
397 if let Some(font_style) = self.0.font_style {
398 f.write_str("font_style")?;
399 f.write_str(": ")?;
400 f.write_str("Some(")?;
401 write!(f, "UserFontStyle::{:?}", font_style)?;
402 f.write_str(")")?;
403 f.write_str(",")?;
404 }
405
406 if let Some(font_weight) = self.0.font_weight.as_ref() {
407 f.write_str("font_weight")?;
408 f.write_str(": ")?;
409 f.write_str("Some(")?;
410 write!(f, "UserFontWeight({:?})", font_weight.0)?;
411 f.write_str(")")?;
412 f.write_str(",")?;
413 }
414
415 f.write_str("..Default::default()")?;
416 f.write_str("}")
417 }
418}