theme_printer.rs

  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}