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            ("conflict_background", self.0.conflict_background),
314            ("conflict_border", self.0.conflict_border),
315            ("created", self.0.created),
316            ("created_background", self.0.created_background),
317            ("created_border", self.0.created_border),
318            ("deleted", self.0.deleted),
319            ("deleted_background", self.0.deleted_background),
320            ("deleted_border", self.0.deleted_border),
321            ("error", self.0.error),
322            ("error_background", self.0.error_background),
323            ("error_border", self.0.error_border),
324            ("hidden", self.0.hidden),
325            ("hidden_background", self.0.hidden_background),
326            ("hidden_border", self.0.hidden_border),
327            ("hint", self.0.hint),
328            ("hint_background", self.0.hint_background),
329            ("hint_border", self.0.hint_border),
330            ("ignored", self.0.ignored),
331            ("ignored_background", self.0.ignored_background),
332            ("ignored_border", self.0.ignored_border),
333            ("info", self.0.info),
334            ("info_background", self.0.info_background),
335            ("info_border", self.0.info_border),
336            ("modified", self.0.modified),
337            ("modified_background", self.0.modified_background),
338            ("modified_border", self.0.modified_border),
339            ("predictive", self.0.predictive),
340            ("predictive_background", self.0.predictive_background),
341            ("predictive_border", self.0.predictive_border),
342            ("renamed", self.0.renamed),
343            ("renamed_background", self.0.renamed_background),
344            ("renamed_border", self.0.renamed_border),
345            ("success", self.0.success),
346            ("success_background", self.0.success_background),
347            ("success_border", self.0.success_border),
348            ("unreachable", self.0.unreachable),
349            ("unreachable_background", self.0.unreachable_background),
350            ("unreachable_border", self.0.unreachable_border),
351            ("warning", self.0.warning),
352            ("warning_background", self.0.warning_background),
353            ("warning_border", self.0.warning_border),
354        ];
355
356        f.write_str("StatusColorsRefinement {")?;
357
358        for (color_name, color) in status_colors {
359            if let Some(color) = color {
360                f.write_str(color_name)?;
361                f.write_str(": ")?;
362                f.write_str("Some(")?;
363                HslaPrinter(color).fmt(f)?;
364                f.write_str(")")?;
365                f.write_str(",")?;
366            }
367        }
368
369        f.write_str("..Default::default()")?;
370        f.write_str("}")
371    }
372}
373
374pub struct PlayerColorsPrinter<'a>(&'a PlayerColors);
375
376impl<'a> Debug for PlayerColorsPrinter<'a> {
377    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
378        f.debug_tuple("PlayerColors")
379            .field(&VecPrinter(
380                &self
381                    .0
382                     .0
383                    .iter()
384                    .map(|player_color| PlayerColorPrinter(player_color))
385                    .collect(),
386            ))
387            .finish()
388    }
389}
390
391pub struct PlayerColorPrinter<'a>(&'a PlayerColor);
392
393impl<'a> Debug for PlayerColorPrinter<'a> {
394    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
395        f.debug_struct("PlayerColor")
396            .field("cursor", &HslaPrinter(self.0.cursor))
397            .field("background", &HslaPrinter(self.0.background))
398            .field("selection", &HslaPrinter(self.0.selection))
399            .finish()
400    }
401}
402
403pub struct UserSyntaxThemePrinter<'a>(&'a UserSyntaxTheme);
404
405impl<'a> Debug for UserSyntaxThemePrinter<'a> {
406    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
407        f.debug_struct("UserSyntaxTheme")
408            .field(
409                "highlights",
410                &VecPrinter(
411                    &self
412                        .0
413                        .highlights
414                        .iter()
415                        .map(|(token, highlight)| {
416                            (IntoPrinter(token), UserHighlightStylePrinter(&highlight))
417                        })
418                        .collect(),
419                ),
420            )
421            .finish()
422    }
423}
424
425pub struct UserHighlightStylePrinter<'a>(&'a UserHighlightStyle);
426
427impl<'a> Debug for UserHighlightStylePrinter<'a> {
428    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
429        f.write_str("UserHighlightStyle {")?;
430
431        if let Some(color) = self.0.color {
432            f.write_str("color")?;
433            f.write_str(": ")?;
434            f.write_str("Some(")?;
435            HslaPrinter(color).fmt(f)?;
436            f.write_str(")")?;
437            f.write_str(",")?;
438        }
439
440        if let Some(font_style) = self.0.font_style {
441            f.write_str("font_style")?;
442            f.write_str(": ")?;
443            f.write_str("Some(")?;
444            write!(f, "UserFontStyle::{:?}", font_style)?;
445            f.write_str(")")?;
446            f.write_str(",")?;
447        }
448
449        if let Some(font_weight) = self.0.font_weight.as_ref() {
450            f.write_str("font_weight")?;
451            f.write_str(": ")?;
452            f.write_str("Some(")?;
453            write!(f, "UserFontWeight({:?})", font_weight.0)?;
454            f.write_str(")")?;
455            f.write_str(",")?;
456        }
457
458        f.write_str("..Default::default()")?;
459        f.write_str("}")
460    }
461}