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