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