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 ("panel_background", self.0.panel_background),
164 ("element_background", self.0.element_background),
165 ("element_hover", self.0.element_hover),
166 ("element_active", self.0.element_active),
167 ("element_selected", self.0.element_selected),
168 ("element_disabled", self.0.element_disabled),
169 ("drop_target_background", self.0.drop_target_background),
170 ("ghost_element_background", self.0.ghost_element_background),
171 ("ghost_element_hover", self.0.ghost_element_hover),
172 ("ghost_element_active", self.0.ghost_element_active),
173 ("ghost_element_selected", self.0.ghost_element_selected),
174 ("ghost_element_disabled", self.0.ghost_element_disabled),
175 ("text", self.0.text),
176 ("text_muted", self.0.text_muted),
177 ("text_placeholder", self.0.text_placeholder),
178 ("text_disabled", self.0.text_disabled),
179 ("text_accent", self.0.text_accent),
180 ("icon", self.0.icon),
181 ("icon_muted", self.0.icon_muted),
182 ("icon_disabled", self.0.icon_disabled),
183 ("icon_placeholder", self.0.icon_placeholder),
184 ("icon_accent", self.0.icon_accent),
185 ("status_bar_background", self.0.status_bar_background),
186 ("title_bar_background", self.0.title_bar_background),
187 ("toolbar_background", self.0.toolbar_background),
188 ("tab_bar_background", self.0.tab_bar_background),
189 ("tab_inactive_background", self.0.tab_inactive_background),
190 ("tab_active_background", self.0.tab_active_background),
191 (
192 "scrollbar_thumb_background",
193 self.0.scrollbar_thumb_background,
194 ),
195 (
196 "scrollbar_thumb_hover_background",
197 self.0.scrollbar_thumb_hover_background,
198 ),
199 ("scrollbar_thumb_border", self.0.scrollbar_thumb_border),
200 (
201 "scrollbar_track_background",
202 self.0.scrollbar_track_background,
203 ),
204 ("scrollbar_track_border", self.0.scrollbar_track_border),
205 ("editor_foreground", self.0.editor_foreground),
206 ("editor_background", self.0.editor_background),
207 ("editor_gutter_background", self.0.editor_gutter_background),
208 (
209 "editor_subheader_background",
210 self.0.editor_subheader_background,
211 ),
212 (
213 "editor_active_line_background",
214 self.0.editor_active_line_background,
215 ),
216 (
217 "editor_highlighted_line_background",
218 self.0.editor_highlighted_line_background,
219 ),
220 ("editor_line_number", self.0.editor_line_number),
221 (
222 "editor_active_line_number",
223 self.0.editor_active_line_number,
224 ),
225 ("editor_invisible", self.0.editor_invisible),
226 ("editor_wrap_guide", self.0.editor_wrap_guide),
227 ("editor_active_wrap_guide", self.0.editor_active_wrap_guide),
228 (
229 "editor_document_highlight_read_background",
230 self.0.editor_document_highlight_read_background,
231 ),
232 (
233 "editor_document_highlight_write_background",
234 self.0.editor_document_highlight_write_background,
235 ),
236 ("terminal_background", self.0.terminal_background),
237 (
238 "terminal_ansi_bright_black",
239 self.0.terminal_ansi_bright_black,
240 ),
241 ("terminal_ansi_bright_red", self.0.terminal_ansi_bright_red),
242 (
243 "terminal_ansi_bright_green",
244 self.0.terminal_ansi_bright_green,
245 ),
246 (
247 "terminal_ansi_bright_yellow",
248 self.0.terminal_ansi_bright_yellow,
249 ),
250 (
251 "terminal_ansi_bright_blue",
252 self.0.terminal_ansi_bright_blue,
253 ),
254 (
255 "terminal_ansi_bright_magenta",
256 self.0.terminal_ansi_bright_magenta,
257 ),
258 (
259 "terminal_ansi_bright_cyan",
260 self.0.terminal_ansi_bright_cyan,
261 ),
262 (
263 "terminal_ansi_bright_white",
264 self.0.terminal_ansi_bright_white,
265 ),
266 ("terminal_ansi_black", self.0.terminal_ansi_black),
267 ("terminal_ansi_red", self.0.terminal_ansi_red),
268 ("terminal_ansi_green", self.0.terminal_ansi_green),
269 ("terminal_ansi_yellow", self.0.terminal_ansi_yellow),
270 ("terminal_ansi_blue", self.0.terminal_ansi_blue),
271 ("terminal_ansi_magenta", self.0.terminal_ansi_magenta),
272 ("terminal_ansi_cyan", self.0.terminal_ansi_cyan),
273 ("terminal_ansi_white", self.0.terminal_ansi_white),
274 ("headline", self.0.headline),
275 ("paragraph", self.0.paragraph),
276 ("link_text", self.0.link_text),
277 ("link_text_hover", self.0.link_text_hover),
278 ("link_uri", self.0.link_uri),
279 ("inline_code_background", self.0.inline_code_background),
280 ("inline_code_border", self.0.inline_code_border),
281 ("code_block_background", self.0.code_block_background),
282 ("code_block_border", self.0.code_block_border),
283 ("emphasis", self.0.emphasis),
284 ];
285
286 f.write_str("ThemeColorsRefinement {")?;
287
288 for (color_name, color) in theme_colors {
289 if let Some(color) = color {
290 f.write_str(color_name)?;
291 f.write_str(": ")?;
292 f.write_str("Some(")?;
293 HslaPrinter(color).fmt(f)?;
294 f.write_str(")")?;
295 f.write_str(",")?;
296 } else {
297 log::warn!(target: "theme_printer", "No value for '{}' in theme", color_name);
298 }
299 }
300
301 f.write_str("..Default::default()")?;
302 f.write_str("}")
303 }
304}
305
306pub struct StatusColorsRefinementPrinter<'a>(&'a StatusColorsRefinement);
307
308impl<'a> Debug for StatusColorsRefinementPrinter<'a> {
309 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
310 let status_colors = vec![
311 ("conflict", self.0.conflict),
312 ("created", self.0.created),
313 ("deleted", self.0.deleted),
314 ("error", self.0.error),
315 ("hidden", self.0.hidden),
316 ("hint", self.0.hint),
317 ("ignored", self.0.ignored),
318 ("info", self.0.info),
319 ("modified", self.0.modified),
320 ("predictive", self.0.predictive),
321 ("renamed", self.0.renamed),
322 ("success", self.0.success),
323 ("unreachable", self.0.unreachable),
324 ("warning", self.0.warning),
325 ];
326
327 f.write_str("StatusColorsRefinement {")?;
328
329 for (color_name, color) in status_colors {
330 if let Some(color) = color {
331 f.write_str(color_name)?;
332 f.write_str(": ")?;
333 f.write_str("Some(")?;
334 HslaPrinter(color).fmt(f)?;
335 f.write_str(")")?;
336 f.write_str(",")?;
337 }
338 }
339
340 f.write_str("..Default::default()")?;
341 f.write_str("}")
342 }
343}
344
345pub struct PlayerColorsPrinter<'a>(&'a PlayerColors);
346
347impl<'a> Debug for PlayerColorsPrinter<'a> {
348 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
349 f.debug_tuple("PlayerColors")
350 .field(&VecPrinter(
351 &self
352 .0
353 .0
354 .iter()
355 .map(|player_color| PlayerColorPrinter(player_color))
356 .collect(),
357 ))
358 .finish()
359 }
360}
361
362pub struct PlayerColorPrinter<'a>(&'a PlayerColor);
363
364impl<'a> Debug for PlayerColorPrinter<'a> {
365 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
366 f.debug_struct("PlayerColor")
367 .field("cursor", &HslaPrinter(self.0.cursor))
368 .field("background", &HslaPrinter(self.0.background))
369 .field("selection", &HslaPrinter(self.0.selection))
370 .finish()
371 }
372}
373
374pub struct UserSyntaxThemePrinter<'a>(&'a UserSyntaxTheme);
375
376impl<'a> Debug for UserSyntaxThemePrinter<'a> {
377 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
378 f.debug_struct("UserSyntaxTheme")
379 .field(
380 "highlights",
381 &VecPrinter(
382 &self
383 .0
384 .highlights
385 .iter()
386 .map(|(token, highlight)| {
387 (IntoPrinter(token), UserHighlightStylePrinter(&highlight))
388 })
389 .collect(),
390 ),
391 )
392 .finish()
393 }
394}
395
396pub struct UserHighlightStylePrinter<'a>(&'a UserHighlightStyle);
397
398impl<'a> Debug for UserHighlightStylePrinter<'a> {
399 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
400 f.write_str("UserHighlightStyle {")?;
401
402 if let Some(color) = self.0.color {
403 f.write_str("color")?;
404 f.write_str(": ")?;
405 f.write_str("Some(")?;
406 HslaPrinter(color).fmt(f)?;
407 f.write_str(")")?;
408 f.write_str(",")?;
409 }
410
411 if let Some(font_style) = self.0.font_style {
412 f.write_str("font_style")?;
413 f.write_str(": ")?;
414 f.write_str("Some(")?;
415 write!(f, "UserFontStyle::{:?}", font_style)?;
416 f.write_str(")")?;
417 f.write_str(",")?;
418 }
419
420 if let Some(font_weight) = self.0.font_weight.as_ref() {
421 f.write_str("font_weight")?;
422 f.write_str(": ")?;
423 f.write_str("Some(")?;
424 write!(f, "UserFontWeight({:?})", font_weight.0)?;
425 f.write_str(")")?;
426 f.write_str(",")?;
427 }
428
429 f.write_str("..Default::default()")?;
430 f.write_str("}")
431 }
432}