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            ("terminal_foreground", self.0.terminal_foreground),
248            (
249                "terminal_bright_foreground",
250                self.0.terminal_bright_foreground,
251            ),
252            ("terminal_dim_foreground", self.0.terminal_dim_foreground),
253            ("terminal_ansi_black", self.0.terminal_ansi_black),
254            (
255                "terminal_ansi_bright_black",
256                self.0.terminal_ansi_bright_black,
257            ),
258            ("terminal_ansi_dim_black", self.0.terminal_ansi_dim_black),
259            ("terminal_ansi_red", self.0.terminal_ansi_red),
260            ("terminal_ansi_bright_red", self.0.terminal_ansi_bright_red),
261            ("terminal_ansi_dim_red", self.0.terminal_ansi_dim_red),
262            ("terminal_ansi_green", self.0.terminal_ansi_green),
263            (
264                "terminal_ansi_bright_green",
265                self.0.terminal_ansi_bright_green,
266            ),
267            ("terminal_ansi_dim_green", self.0.terminal_ansi_dim_green),
268            ("terminal_ansi_yellow", self.0.terminal_ansi_yellow),
269            (
270                "terminal_ansi_bright_yellow",
271                self.0.terminal_ansi_bright_yellow,
272            ),
273            ("terminal_ansi_dim_yellow", self.0.terminal_ansi_dim_yellow),
274            ("terminal_ansi_blue", self.0.terminal_ansi_blue),
275            (
276                "terminal_ansi_bright_blue",
277                self.0.terminal_ansi_bright_blue,
278            ),
279            ("terminal_ansi_dim_blue", self.0.terminal_ansi_dim_blue),
280            ("terminal_ansi_magenta", self.0.terminal_ansi_magenta),
281            (
282                "terminal_ansi_bright_magenta",
283                self.0.terminal_ansi_bright_magenta,
284            ),
285            (
286                "terminal_ansi_dim_magenta",
287                self.0.terminal_ansi_dim_magenta,
288            ),
289            ("terminal_ansi_cyan", self.0.terminal_ansi_cyan),
290            (
291                "terminal_ansi_bright_cyan",
292                self.0.terminal_ansi_bright_cyan,
293            ),
294            ("terminal_ansi_dim_cyan", self.0.terminal_ansi_dim_cyan),
295            ("terminal_ansi_white", self.0.terminal_ansi_white),
296            (
297                "terminal_ansi_bright_white",
298                self.0.terminal_ansi_bright_white,
299            ),
300            ("terminal_ansi_dim_white", self.0.terminal_ansi_dim_white),
301            ("link_text_hover", self.0.link_text_hover),
302        ];
303
304        f.write_str("ThemeColorsRefinement {")?;
305
306        for (color_name, color) in theme_colors {
307            if let Some(color) = color {
308                f.write_str(color_name)?;
309                f.write_str(": ")?;
310                f.write_str("Some(")?;
311                HslaPrinter(color).fmt(f)?;
312                f.write_str(")")?;
313                f.write_str(",")?;
314            } else {
315                log::warn!(target: "theme_printer", "No value for '{}' in theme", color_name);
316            }
317        }
318
319        f.write_str("..Default::default()")?;
320        f.write_str("}")
321    }
322}
323
324pub struct StatusColorsRefinementPrinter<'a>(&'a StatusColorsRefinement);
325
326impl<'a> Debug for StatusColorsRefinementPrinter<'a> {
327    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
328        let status_colors = vec![
329            ("conflict", self.0.conflict),
330            ("conflict_background", self.0.conflict_background),
331            ("conflict_border", self.0.conflict_border),
332            ("created", self.0.created),
333            ("created_background", self.0.created_background),
334            ("created_border", self.0.created_border),
335            ("deleted", self.0.deleted),
336            ("deleted_background", self.0.deleted_background),
337            ("deleted_border", self.0.deleted_border),
338            ("error", self.0.error),
339            ("error_background", self.0.error_background),
340            ("error_border", self.0.error_border),
341            ("hidden", self.0.hidden),
342            ("hidden_background", self.0.hidden_background),
343            ("hidden_border", self.0.hidden_border),
344            ("hint", self.0.hint),
345            ("hint_background", self.0.hint_background),
346            ("hint_border", self.0.hint_border),
347            ("ignored", self.0.ignored),
348            ("ignored_background", self.0.ignored_background),
349            ("ignored_border", self.0.ignored_border),
350            ("info", self.0.info),
351            ("info_background", self.0.info_background),
352            ("info_border", self.0.info_border),
353            ("modified", self.0.modified),
354            ("modified_background", self.0.modified_background),
355            ("modified_border", self.0.modified_border),
356            ("predictive", self.0.predictive),
357            ("predictive_background", self.0.predictive_background),
358            ("predictive_border", self.0.predictive_border),
359            ("renamed", self.0.renamed),
360            ("renamed_background", self.0.renamed_background),
361            ("renamed_border", self.0.renamed_border),
362            ("success", self.0.success),
363            ("success_background", self.0.success_background),
364            ("success_border", self.0.success_border),
365            ("unreachable", self.0.unreachable),
366            ("unreachable_background", self.0.unreachable_background),
367            ("unreachable_border", self.0.unreachable_border),
368            ("warning", self.0.warning),
369            ("warning_background", self.0.warning_background),
370            ("warning_border", self.0.warning_border),
371        ];
372
373        f.write_str("StatusColorsRefinement {")?;
374
375        for (color_name, color) in status_colors {
376            if let Some(color) = color {
377                f.write_str(color_name)?;
378                f.write_str(": ")?;
379                f.write_str("Some(")?;
380                HslaPrinter(color).fmt(f)?;
381                f.write_str(")")?;
382                f.write_str(",")?;
383            }
384        }
385
386        f.write_str("..Default::default()")?;
387        f.write_str("}")
388    }
389}
390
391pub struct PlayerColorsPrinter<'a>(&'a PlayerColors);
392
393impl<'a> Debug for PlayerColorsPrinter<'a> {
394    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
395        f.debug_tuple("PlayerColors")
396            .field(&VecPrinter(
397                &self
398                    .0
399                     .0
400                    .iter()
401                    .map(|player_color| PlayerColorPrinter(player_color))
402                    .collect(),
403            ))
404            .finish()
405    }
406}
407
408pub struct PlayerColorPrinter<'a>(&'a PlayerColor);
409
410impl<'a> Debug for PlayerColorPrinter<'a> {
411    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
412        f.debug_struct("PlayerColor")
413            .field("cursor", &HslaPrinter(self.0.cursor))
414            .field("background", &HslaPrinter(self.0.background))
415            .field("selection", &HslaPrinter(self.0.selection))
416            .finish()
417    }
418}
419
420pub struct UserSyntaxThemePrinter<'a>(&'a UserSyntaxTheme);
421
422impl<'a> Debug for UserSyntaxThemePrinter<'a> {
423    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
424        f.debug_struct("UserSyntaxTheme")
425            .field(
426                "highlights",
427                &VecPrinter(
428                    &self
429                        .0
430                        .highlights
431                        .iter()
432                        .map(|(token, highlight)| {
433                            (IntoPrinter(token), UserHighlightStylePrinter(&highlight))
434                        })
435                        .collect(),
436                ),
437            )
438            .finish()
439    }
440}
441
442pub struct UserHighlightStylePrinter<'a>(&'a UserHighlightStyle);
443
444impl<'a> Debug for UserHighlightStylePrinter<'a> {
445    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
446        f.write_str("UserHighlightStyle {")?;
447
448        if let Some(color) = self.0.color {
449            f.write_str("color")?;
450            f.write_str(": ")?;
451            f.write_str("Some(")?;
452            HslaPrinter(color).fmt(f)?;
453            f.write_str(")")?;
454            f.write_str(",")?;
455        }
456
457        if let Some(font_style) = self.0.font_style {
458            f.write_str("font_style")?;
459            f.write_str(": ")?;
460            f.write_str("Some(")?;
461            write!(f, "UserFontStyle::{:?}", font_style)?;
462            f.write_str(")")?;
463            f.write_str(",")?;
464        }
465
466        if let Some(font_weight) = self.0.font_weight.as_ref() {
467            f.write_str("font_weight")?;
468            f.write_str(": ")?;
469            f.write_str("Some(")?;
470            write!(f, "UserFontWeight({:?})", font_weight.0)?;
471            f.write_str(")")?;
472            f.write_str(",")?;
473        }
474
475        f.write_str("..Default::default()")?;
476        f.write_str("}")
477    }
478}