1use std::fmt::{self, Debug};
2
3use gpui::{Hsla, Rgba};
4use theme::{
5 Appearance, PlayerColor, PlayerColors, StatusColorsRefinement, SystemColors,
6 ThemeColorsRefinement, UserSyntaxTheme, UserTheme, UserThemeFamily, UserThemeStylesRefinement,
7};
8
9struct RawSyntaxPrinter<'a>(&'a str);
10
11impl<'a> Debug for RawSyntaxPrinter<'a> {
12 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13 write!(f, "{}", self.0)
14 }
15}
16
17struct HslaPrinter(Hsla);
18
19impl Debug for HslaPrinter {
20 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
21 write!(f, "{:?}", IntoPrinter(&Rgba::from(self.0)))
22 }
23}
24
25struct IntoPrinter<'a, D: Debug>(&'a D);
26
27impl<'a, D: Debug> Debug for IntoPrinter<'a, D> {
28 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29 write!(f, "{:?}.into()", self.0)
30 }
31}
32
33pub struct OptionPrinter<'a, T>(&'a Option<T>);
34
35impl<'a, T: Debug> Debug for OptionPrinter<'a, T> {
36 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37 match self.0 {
38 Some(value) => write!(f, "Some({:?})", value),
39 None => write!(f, "None"),
40 }
41 }
42}
43
44pub struct VecPrinter<'a, T>(&'a Vec<T>);
45
46impl<'a, T: Debug> Debug for VecPrinter<'a, T> {
47 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48 write!(f, "vec!{:?}", &self.0)
49 }
50}
51
52pub struct UserThemeFamilyPrinter(UserThemeFamily);
53
54impl UserThemeFamilyPrinter {
55 pub fn new(theme_family: UserThemeFamily) -> Self {
56 Self(theme_family)
57 }
58}
59
60impl Debug for UserThemeFamilyPrinter {
61 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62 f.debug_struct("UserThemeFamily")
63 .field("name", &IntoPrinter(&self.0.name))
64 .field("author", &IntoPrinter(&self.0.author))
65 .field(
66 "themes",
67 &VecPrinter(
68 &self
69 .0
70 .themes
71 .iter()
72 .map(|theme| UserThemePrinter(theme))
73 .collect(),
74 ),
75 )
76 .finish()
77 }
78}
79
80pub struct UserThemePrinter<'a>(&'a UserTheme);
81
82impl<'a> Debug for UserThemePrinter<'a> {
83 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
84 f.debug_struct("UserTheme")
85 .field("name", &IntoPrinter(&self.0.name))
86 .field("appearance", &AppearancePrinter(self.0.appearance))
87 .field("styles", &UserThemeStylesRefinementPrinter(&self.0.styles))
88 .finish()
89 }
90}
91
92pub struct AppearancePrinter(Appearance);
93
94impl Debug for AppearancePrinter {
95 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96 write!(f, "Appearance::{:?}", self.0)
97 }
98}
99
100pub struct UserThemeStylesRefinementPrinter<'a>(&'a UserThemeStylesRefinement);
101
102impl<'a> Debug for UserThemeStylesRefinementPrinter<'a> {
103 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104 f.debug_struct("UserThemeStylesRefinement")
105 .field("colors", &ThemeColorsRefinementPrinter(&self.0.colors))
106 .field("status", &StatusColorsRefinementPrinter(&self.0.status))
107 .field(
108 "syntax",
109 &OptionPrinter(
110 &self
111 .0
112 .syntax
113 .as_ref()
114 .map(|syntax| UserSyntaxThemePrinter(syntax)),
115 ),
116 )
117 .finish()
118 }
119}
120
121pub struct SystemColorsPrinter<'a>(&'a SystemColors);
122
123impl<'a> Debug for SystemColorsPrinter<'a> {
124 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
125 f.debug_struct("SystemColors")
126 .field("transparent", &HslaPrinter(self.0.transparent))
127 .field(
128 "mac_os_traffic_light_red",
129 &HslaPrinter(self.0.mac_os_traffic_light_red),
130 )
131 .field(
132 "mac_os_traffic_light_yellow",
133 &HslaPrinter(self.0.mac_os_traffic_light_yellow),
134 )
135 .field(
136 "mac_os_traffic_light_green",
137 &HslaPrinter(self.0.mac_os_traffic_light_green),
138 )
139 .finish()
140 }
141}
142
143pub struct ThemeColorsRefinementPrinter<'a>(&'a ThemeColorsRefinement);
144
145impl<'a> Debug for ThemeColorsRefinementPrinter<'a> {
146 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
147 let theme_colors = vec![
148 ("border", self.0.border),
149 ("border_variant", self.0.border_variant),
150 ("border_focused", self.0.border_focused),
151 ("border_selected", self.0.border_selected),
152 ("border_transparent", self.0.border_transparent),
153 ("border_disabled", self.0.border_disabled),
154 (
155 "elevated_surface_background",
156 self.0.elevated_surface_background,
157 ),
158 ("surface_background", self.0.surface_background),
159 ("background", self.0.background),
160 ("element_background", self.0.element_background),
161 ("element_hover", self.0.element_hover),
162 ("element_active", self.0.element_active),
163 ("element_selected", self.0.element_selected),
164 ("element_disabled", self.0.element_disabled),
165 ("drop_target_background", self.0.drop_target_background),
166 ("ghost_element_background", self.0.ghost_element_background),
167 ("ghost_element_hover", self.0.ghost_element_hover),
168 ("ghost_element_active", self.0.ghost_element_active),
169 ("ghost_element_selected", self.0.ghost_element_selected),
170 ("ghost_element_disabled", self.0.ghost_element_disabled),
171 ("text", self.0.text),
172 ("text_muted", self.0.text_muted),
173 ("text_placeholder", self.0.text_placeholder),
174 ("text_disabled", self.0.text_disabled),
175 ("text_accent", self.0.text_accent),
176 ("icon", self.0.icon),
177 ("icon_muted", self.0.icon_muted),
178 ("icon_disabled", self.0.icon_disabled),
179 ("icon_placeholder", self.0.icon_placeholder),
180 ("icon_accent", self.0.icon_accent),
181 ("status_bar_background", self.0.status_bar_background),
182 ("title_bar_background", self.0.title_bar_background),
183 ("toolbar_background", self.0.toolbar_background),
184 ("tab_bar_background", self.0.tab_bar_background),
185 ("tab_inactive_background", self.0.tab_inactive_background),
186 ("tab_active_background", self.0.tab_active_background),
187 ("editor_background", self.0.editor_background),
188 ("editor_gutter_background", self.0.editor_gutter_background),
189 (
190 "editor_subheader_background",
191 self.0.editor_subheader_background,
192 ),
193 (
194 "editor_active_line_background",
195 self.0.editor_active_line_background,
196 ),
197 (
198 "editor_highlighted_line_background",
199 self.0.editor_highlighted_line_background,
200 ),
201 ("editor_line_number", self.0.editor_line_number),
202 (
203 "editor_active_line_number",
204 self.0.editor_active_line_number,
205 ),
206 ("editor_invisible", self.0.editor_invisible),
207 ("editor_wrap_guide", self.0.editor_wrap_guide),
208 ("editor_active_wrap_guide", self.0.editor_active_wrap_guide),
209 (
210 "editor_document_highlight_read_background",
211 self.0.editor_document_highlight_read_background,
212 ),
213 (
214 "editor_document_highlight_write_background",
215 self.0.editor_document_highlight_write_background,
216 ),
217 ("terminal_background", self.0.terminal_background),
218 (
219 "terminal_ansi_bright_black",
220 self.0.terminal_ansi_bright_black,
221 ),
222 ("terminal_ansi_bright_red", self.0.terminal_ansi_bright_red),
223 (
224 "terminal_ansi_bright_green",
225 self.0.terminal_ansi_bright_green,
226 ),
227 (
228 "terminal_ansi_bright_yellow",
229 self.0.terminal_ansi_bright_yellow,
230 ),
231 (
232 "terminal_ansi_bright_blue",
233 self.0.terminal_ansi_bright_blue,
234 ),
235 (
236 "terminal_ansi_bright_magenta",
237 self.0.terminal_ansi_bright_magenta,
238 ),
239 (
240 "terminal_ansi_bright_cyan",
241 self.0.terminal_ansi_bright_cyan,
242 ),
243 (
244 "terminal_ansi_bright_white",
245 self.0.terminal_ansi_bright_white,
246 ),
247 ("terminal_ansi_black", self.0.terminal_ansi_black),
248 ("terminal_ansi_red", self.0.terminal_ansi_red),
249 ("terminal_ansi_green", self.0.terminal_ansi_green),
250 ("terminal_ansi_yellow", self.0.terminal_ansi_yellow),
251 ("terminal_ansi_blue", self.0.terminal_ansi_blue),
252 ("terminal_ansi_magenta", self.0.terminal_ansi_magenta),
253 ("terminal_ansi_cyan", self.0.terminal_ansi_cyan),
254 ("terminal_ansi_white", self.0.terminal_ansi_white),
255 ];
256
257 f.write_str("ThemeColorsRefinement {")?;
258
259 for (color_name, color) in theme_colors {
260 if let Some(color) = color {
261 f.write_str(color_name)?;
262 f.write_str(": ")?;
263 f.write_str("Some(")?;
264 HslaPrinter(color).fmt(f)?;
265 f.write_str(")")?;
266 f.write_str(",")?;
267 }
268 }
269
270 f.write_str("..Default::default()")?;
271 f.write_str("}")
272 }
273}
274
275pub struct StatusColorsRefinementPrinter<'a>(&'a StatusColorsRefinement);
276
277impl<'a> Debug for StatusColorsRefinementPrinter<'a> {
278 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
279 let status_colors = vec![
280 ("conflict", self.0.conflict),
281 ("created", self.0.created),
282 ("deleted", self.0.deleted),
283 ("error", self.0.error),
284 ("hidden", self.0.hidden),
285 ("ignored", self.0.ignored),
286 ("info", self.0.info),
287 ("modified", self.0.modified),
288 ("renamed", self.0.renamed),
289 ("success", self.0.success),
290 ("warning", self.0.warning),
291 ];
292
293 f.write_str("StatusColorsRefinement {")?;
294
295 for (color_name, color) in status_colors {
296 if let Some(color) = color {
297 f.write_str(color_name)?;
298 f.write_str(": ")?;
299 f.write_str("Some(")?;
300 HslaPrinter(color).fmt(f)?;
301 f.write_str(")")?;
302 f.write_str(",")?;
303 }
304 }
305
306 f.write_str("..Default::default()")?;
307 f.write_str("}")
308 }
309}
310
311pub struct PlayerColorsPrinter<'a>(&'a PlayerColors);
312
313impl<'a> Debug for PlayerColorsPrinter<'a> {
314 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
315 f.debug_tuple("PlayerColors")
316 .field(&VecPrinter(
317 &self
318 .0
319 .0
320 .iter()
321 .map(|player_color| PlayerColorPrinter(player_color))
322 .collect(),
323 ))
324 .finish()
325 }
326}
327
328pub struct PlayerColorPrinter<'a>(&'a PlayerColor);
329
330impl<'a> Debug for PlayerColorPrinter<'a> {
331 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
332 f.debug_struct("PlayerColor")
333 .field("cursor", &HslaPrinter(self.0.cursor))
334 .field("background", &HslaPrinter(self.0.background))
335 .field("selection", &HslaPrinter(self.0.selection))
336 .finish()
337 }
338}
339
340pub struct UserSyntaxThemePrinter<'a>(&'a UserSyntaxTheme);
341
342impl<'a> Debug for UserSyntaxThemePrinter<'a> {
343 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
344 f.debug_struct("UserSyntaxTheme")
345 .field(
346 "highlights",
347 &VecPrinter(
348 &self
349 .0
350 .highlights
351 .iter()
352 .map(|(token, highlight)| {
353 (IntoPrinter(token), HslaPrinter(highlight.color.unwrap()))
354 })
355 .collect(),
356 ),
357 )
358 .finish()
359 }
360}