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            ("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}