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