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