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                "player",
112                &OptionPrinter(
113                    &self
114                        .0
115                        .player
116                        .as_ref()
117                        .map(|player_colors| PlayerColorsPrinter(player_colors)),
118                ),
119            )
120            .field(
121                "syntax",
122                &OptionPrinter(
123                    &self
124                        .0
125                        .syntax
126                        .as_ref()
127                        .map(|syntax| UserSyntaxThemePrinter(syntax)),
128                ),
129            )
130            .finish()
131    }
132}
133
134pub struct SystemColorsPrinter<'a>(&'a SystemColors);
135
136impl<'a> Debug for SystemColorsPrinter<'a> {
137    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
138        f.debug_struct("SystemColors")
139            .field("transparent", &HslaPrinter(self.0.transparent))
140            .field(
141                "mac_os_traffic_light_red",
142                &HslaPrinter(self.0.mac_os_traffic_light_red),
143            )
144            .field(
145                "mac_os_traffic_light_yellow",
146                &HslaPrinter(self.0.mac_os_traffic_light_yellow),
147            )
148            .field(
149                "mac_os_traffic_light_green",
150                &HslaPrinter(self.0.mac_os_traffic_light_green),
151            )
152            .finish()
153    }
154}
155
156pub struct ThemeColorsRefinementPrinter<'a>(&'a ThemeColorsRefinement);
157
158impl<'a> Debug for ThemeColorsRefinementPrinter<'a> {
159    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
160        let theme_colors = vec![
161            ("border", self.0.border),
162            ("border_variant", self.0.border_variant),
163            ("border_focused", self.0.border_focused),
164            ("border_selected", self.0.border_selected),
165            ("border_transparent", self.0.border_transparent),
166            ("border_disabled", self.0.border_disabled),
167            (
168                "elevated_surface_background",
169                self.0.elevated_surface_background,
170            ),
171            ("surface_background", self.0.surface_background),
172            ("background", self.0.background),
173            ("panel_background", self.0.panel_background),
174            ("element_background", self.0.element_background),
175            ("element_hover", self.0.element_hover),
176            ("element_active", self.0.element_active),
177            ("element_selected", self.0.element_selected),
178            ("element_disabled", self.0.element_disabled),
179            ("drop_target_background", self.0.drop_target_background),
180            ("ghost_element_background", self.0.ghost_element_background),
181            ("ghost_element_hover", self.0.ghost_element_hover),
182            ("ghost_element_active", self.0.ghost_element_active),
183            ("ghost_element_selected", self.0.ghost_element_selected),
184            ("ghost_element_disabled", self.0.ghost_element_disabled),
185            ("text", self.0.text),
186            ("text_muted", self.0.text_muted),
187            ("text_placeholder", self.0.text_placeholder),
188            ("text_disabled", self.0.text_disabled),
189            ("text_accent", self.0.text_accent),
190            ("icon", self.0.icon),
191            ("icon_muted", self.0.icon_muted),
192            ("icon_disabled", self.0.icon_disabled),
193            ("icon_placeholder", self.0.icon_placeholder),
194            ("icon_accent", self.0.icon_accent),
195            ("status_bar_background", self.0.status_bar_background),
196            ("title_bar_background", self.0.title_bar_background),
197            ("toolbar_background", self.0.toolbar_background),
198            ("tab_bar_background", self.0.tab_bar_background),
199            ("tab_inactive_background", self.0.tab_inactive_background),
200            ("tab_active_background", self.0.tab_active_background),
201            (
202                "scrollbar_thumb_background",
203                self.0.scrollbar_thumb_background,
204            ),
205            (
206                "scrollbar_thumb_hover_background",
207                self.0.scrollbar_thumb_hover_background,
208            ),
209            ("scrollbar_thumb_border", self.0.scrollbar_thumb_border),
210            (
211                "scrollbar_track_background",
212                self.0.scrollbar_track_background,
213            ),
214            ("scrollbar_track_border", self.0.scrollbar_track_border),
215            ("editor_foreground", self.0.editor_foreground),
216            ("editor_background", self.0.editor_background),
217            ("editor_gutter_background", self.0.editor_gutter_background),
218            (
219                "editor_subheader_background",
220                self.0.editor_subheader_background,
221            ),
222            (
223                "editor_active_line_background",
224                self.0.editor_active_line_background,
225            ),
226            (
227                "editor_highlighted_line_background",
228                self.0.editor_highlighted_line_background,
229            ),
230            ("editor_line_number", self.0.editor_line_number),
231            (
232                "editor_active_line_number",
233                self.0.editor_active_line_number,
234            ),
235            ("editor_invisible", self.0.editor_invisible),
236            ("editor_wrap_guide", self.0.editor_wrap_guide),
237            ("editor_active_wrap_guide", self.0.editor_active_wrap_guide),
238            (
239                "editor_document_highlight_read_background",
240                self.0.editor_document_highlight_read_background,
241            ),
242            (
243                "editor_document_highlight_write_background",
244                self.0.editor_document_highlight_write_background,
245            ),
246            ("terminal_background", self.0.terminal_background),
247            (
248                "terminal_ansi_bright_black",
249                self.0.terminal_ansi_bright_black,
250            ),
251            ("terminal_ansi_bright_red", self.0.terminal_ansi_bright_red),
252            (
253                "terminal_ansi_bright_green",
254                self.0.terminal_ansi_bright_green,
255            ),
256            (
257                "terminal_ansi_bright_yellow",
258                self.0.terminal_ansi_bright_yellow,
259            ),
260            (
261                "terminal_ansi_bright_blue",
262                self.0.terminal_ansi_bright_blue,
263            ),
264            (
265                "terminal_ansi_bright_magenta",
266                self.0.terminal_ansi_bright_magenta,
267            ),
268            (
269                "terminal_ansi_bright_cyan",
270                self.0.terminal_ansi_bright_cyan,
271            ),
272            (
273                "terminal_ansi_bright_white",
274                self.0.terminal_ansi_bright_white,
275            ),
276            ("terminal_ansi_black", self.0.terminal_ansi_black),
277            ("terminal_ansi_red", self.0.terminal_ansi_red),
278            ("terminal_ansi_green", self.0.terminal_ansi_green),
279            ("terminal_ansi_yellow", self.0.terminal_ansi_yellow),
280            ("terminal_ansi_blue", self.0.terminal_ansi_blue),
281            ("terminal_ansi_magenta", self.0.terminal_ansi_magenta),
282            ("terminal_ansi_cyan", self.0.terminal_ansi_cyan),
283            ("terminal_ansi_white", self.0.terminal_ansi_white),
284            ("link_text_hover", self.0.link_text_hover),
285        ];
286
287        f.write_str("ThemeColorsRefinement {")?;
288
289        for (color_name, color) in theme_colors {
290            if let Some(color) = color {
291                f.write_str(color_name)?;
292                f.write_str(": ")?;
293                f.write_str("Some(")?;
294                HslaPrinter(color).fmt(f)?;
295                f.write_str(")")?;
296                f.write_str(",")?;
297            } else {
298                log::warn!(target: "theme_printer", "No value for '{}' in theme", color_name);
299            }
300        }
301
302        f.write_str("..Default::default()")?;
303        f.write_str("}")
304    }
305}
306
307pub struct StatusColorsRefinementPrinter<'a>(&'a StatusColorsRefinement);
308
309impl<'a> Debug for StatusColorsRefinementPrinter<'a> {
310    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
311        let status_colors = vec![
312            ("conflict", self.0.conflict),
313            ("created", self.0.created),
314            ("deleted", self.0.deleted),
315            ("error", self.0.error),
316            ("hidden", self.0.hidden),
317            ("hint", self.0.hint),
318            ("ignored", self.0.ignored),
319            ("info", self.0.info),
320            ("modified", self.0.modified),
321            ("predictive", self.0.predictive),
322            ("renamed", self.0.renamed),
323            ("success", self.0.success),
324            ("unreachable", self.0.unreachable),
325            ("warning", self.0.warning),
326        ];
327
328        f.write_str("StatusColorsRefinement {")?;
329
330        for (color_name, color) in status_colors {
331            if let Some(color) = color {
332                f.write_str(color_name)?;
333                f.write_str(": ")?;
334                f.write_str("Some(")?;
335                HslaPrinter(color).fmt(f)?;
336                f.write_str(")")?;
337                f.write_str(",")?;
338            }
339        }
340
341        f.write_str("..Default::default()")?;
342        f.write_str("}")
343    }
344}
345
346pub struct PlayerColorsPrinter<'a>(&'a PlayerColors);
347
348impl<'a> Debug for PlayerColorsPrinter<'a> {
349    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
350        f.debug_tuple("PlayerColors")
351            .field(&VecPrinter(
352                &self
353                    .0
354                     .0
355                    .iter()
356                    .map(|player_color| PlayerColorPrinter(player_color))
357                    .collect(),
358            ))
359            .finish()
360    }
361}
362
363pub struct PlayerColorPrinter<'a>(&'a PlayerColor);
364
365impl<'a> Debug for PlayerColorPrinter<'a> {
366    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
367        f.debug_struct("PlayerColor")
368            .field("cursor", &HslaPrinter(self.0.cursor))
369            .field("background", &HslaPrinter(self.0.background))
370            .field("selection", &HslaPrinter(self.0.selection))
371            .finish()
372    }
373}
374
375pub struct UserSyntaxThemePrinter<'a>(&'a UserSyntaxTheme);
376
377impl<'a> Debug for UserSyntaxThemePrinter<'a> {
378    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
379        f.debug_struct("UserSyntaxTheme")
380            .field(
381                "highlights",
382                &VecPrinter(
383                    &self
384                        .0
385                        .highlights
386                        .iter()
387                        .map(|(token, highlight)| {
388                            (IntoPrinter(token), UserHighlightStylePrinter(&highlight))
389                        })
390                        .collect(),
391                ),
392            )
393            .finish()
394    }
395}
396
397pub struct UserHighlightStylePrinter<'a>(&'a UserHighlightStyle);
398
399impl<'a> Debug for UserHighlightStylePrinter<'a> {
400    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
401        f.write_str("UserHighlightStyle {")?;
402
403        if let Some(color) = self.0.color {
404            f.write_str("color")?;
405            f.write_str(": ")?;
406            f.write_str("Some(")?;
407            HslaPrinter(color).fmt(f)?;
408            f.write_str(")")?;
409            f.write_str(",")?;
410        }
411
412        if let Some(font_style) = self.0.font_style {
413            f.write_str("font_style")?;
414            f.write_str(": ")?;
415            f.write_str("Some(")?;
416            write!(f, "UserFontStyle::{:?}", font_style)?;
417            f.write_str(")")?;
418            f.write_str(",")?;
419        }
420
421        if let Some(font_weight) = self.0.font_weight.as_ref() {
422            f.write_str("font_weight")?;
423            f.write_str(": ")?;
424            f.write_str("Some(")?;
425            write!(f, "UserFontWeight({:?})", font_weight.0)?;
426            f.write_str(")")?;
427            f.write_str(",")?;
428        }
429
430        f.write_str("..Default::default()")?;
431        f.write_str("}")
432    }
433}