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            } else {
286                log::warn!(target: "theme_printer", "No value for '{}' in theme", color_name);
287            }
288        }
289
290        f.write_str("..Default::default()")?;
291        f.write_str("}")
292    }
293}
294
295pub struct StatusColorsRefinementPrinter<'a>(&'a StatusColorsRefinement);
296
297impl<'a> Debug for StatusColorsRefinementPrinter<'a> {
298    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
299        let status_colors = vec![
300            ("conflict", self.0.conflict),
301            ("created", self.0.created),
302            ("deleted", self.0.deleted),
303            ("error", self.0.error),
304            ("hidden", self.0.hidden),
305            ("hint", self.0.hint),
306            ("ignored", self.0.ignored),
307            ("info", self.0.info),
308            ("modified", self.0.modified),
309            ("predictive", self.0.predictive),
310            ("renamed", self.0.renamed),
311            ("success", self.0.success),
312            ("unreachable", self.0.unreachable),
313            ("warning", self.0.warning),
314        ];
315
316        f.write_str("StatusColorsRefinement {")?;
317
318        for (color_name, color) in status_colors {
319            if let Some(color) = color {
320                f.write_str(color_name)?;
321                f.write_str(": ")?;
322                f.write_str("Some(")?;
323                HslaPrinter(color).fmt(f)?;
324                f.write_str(")")?;
325                f.write_str(",")?;
326            }
327        }
328
329        f.write_str("..Default::default()")?;
330        f.write_str("}")
331    }
332}
333
334pub struct PlayerColorsPrinter<'a>(&'a PlayerColors);
335
336impl<'a> Debug for PlayerColorsPrinter<'a> {
337    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
338        f.debug_tuple("PlayerColors")
339            .field(&VecPrinter(
340                &self
341                    .0
342                     .0
343                    .iter()
344                    .map(|player_color| PlayerColorPrinter(player_color))
345                    .collect(),
346            ))
347            .finish()
348    }
349}
350
351pub struct PlayerColorPrinter<'a>(&'a PlayerColor);
352
353impl<'a> Debug for PlayerColorPrinter<'a> {
354    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
355        f.debug_struct("PlayerColor")
356            .field("cursor", &HslaPrinter(self.0.cursor))
357            .field("background", &HslaPrinter(self.0.background))
358            .field("selection", &HslaPrinter(self.0.selection))
359            .finish()
360    }
361}
362
363pub struct UserSyntaxThemePrinter<'a>(&'a UserSyntaxTheme);
364
365impl<'a> Debug for UserSyntaxThemePrinter<'a> {
366    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
367        f.debug_struct("UserSyntaxTheme")
368            .field(
369                "highlights",
370                &VecPrinter(
371                    &self
372                        .0
373                        .highlights
374                        .iter()
375                        .map(|(token, highlight)| {
376                            (IntoPrinter(token), UserHighlightStylePrinter(&highlight))
377                        })
378                        .collect(),
379                ),
380            )
381            .finish()
382    }
383}
384
385pub struct UserHighlightStylePrinter<'a>(&'a UserHighlightStyle);
386
387impl<'a> Debug for UserHighlightStylePrinter<'a> {
388    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
389        f.write_str("UserHighlightStyle {")?;
390
391        if let Some(color) = self.0.color {
392            f.write_str("color")?;
393            f.write_str(": ")?;
394            f.write_str("Some(")?;
395            HslaPrinter(color).fmt(f)?;
396            f.write_str(")")?;
397            f.write_str(",")?;
398        }
399
400        if let Some(font_style) = self.0.font_style {
401            f.write_str("font_style")?;
402            f.write_str(": ")?;
403            f.write_str("Some(")?;
404            write!(f, "UserFontStyle::{:?}", font_style)?;
405            f.write_str(")")?;
406            f.write_str(",")?;
407        }
408
409        if let Some(font_weight) = self.0.font_weight.as_ref() {
410            f.write_str("font_weight")?;
411            f.write_str(": ")?;
412            f.write_str("Some(")?;
413            write!(f, "UserFontWeight({:?})", font_weight.0)?;
414            f.write_str(")")?;
415            f.write_str(",")?;
416        }
417
418        f.write_str("..Default::default()")?;
419        f.write_str("}")
420    }
421}