registry.rs

 1use std::collections::HashMap;
 2use std::sync::Arc;
 3
 4use anyhow::{anyhow, Result};
 5use gpui::SharedString;
 6use refineable::Refineable;
 7
 8use crate::{
 9    zed_pro_family, Appearance, GitStatusColors, PlayerColors, StatusColors, SyntaxTheme,
10    SystemColors, Theme, ThemeColors, ThemeFamily, ThemeStyles, UserTheme, UserThemeFamily,
11};
12
13pub struct ThemeRegistry {
14    themes: HashMap<SharedString, Arc<Theme>>,
15}
16
17impl ThemeRegistry {
18    fn insert_theme_families(&mut self, families: impl IntoIterator<Item = ThemeFamily>) {
19        for family in families.into_iter() {
20            self.insert_themes(family.themes);
21        }
22    }
23
24    fn insert_themes(&mut self, themes: impl IntoIterator<Item = Theme>) {
25        for theme in themes.into_iter() {
26            self.themes.insert(theme.name.clone(), Arc::new(theme));
27        }
28    }
29
30    fn insert_user_theme_familes(&mut self, families: impl IntoIterator<Item = UserThemeFamily>) {
31        for family in families.into_iter() {
32            self.insert_user_themes(family.themes);
33        }
34    }
35
36    fn insert_user_themes(&mut self, themes: impl IntoIterator<Item = UserTheme>) {
37        self.insert_themes(themes.into_iter().map(|user_theme| {
38            let mut theme_colors = match user_theme.appearance {
39                Appearance::Light => ThemeColors::default_light(),
40                Appearance::Dark => ThemeColors::default_dark(),
41            };
42
43            theme_colors.refine(&user_theme.styles.colors);
44
45            Theme {
46                id: uuid::Uuid::new_v4().to_string(),
47                name: user_theme.name.into(),
48                appearance: user_theme.appearance,
49                styles: ThemeStyles {
50                    system: SystemColors::default(),
51                    colors: theme_colors,
52                    status: StatusColors::default(),
53                    git: GitStatusColors::default(),
54                    player: PlayerColors::default(),
55                    syntax: match user_theme.appearance {
56                        Appearance::Light => Arc::new(SyntaxTheme::default_light()),
57                        Appearance::Dark => Arc::new(SyntaxTheme::default_dark()),
58                    },
59                },
60            }
61        }));
62    }
63
64    pub fn list_names(&self, _staff: bool) -> impl Iterator<Item = SharedString> + '_ {
65        self.themes.keys().cloned()
66    }
67
68    pub fn list(&self, _staff: bool) -> impl Iterator<Item = SharedString> + '_ {
69        self.themes.values().map(|theme| theme.name.clone())
70    }
71
72    pub fn get(&self, name: &str) -> Result<Arc<Theme>> {
73        self.themes
74            .get(name)
75            .ok_or_else(|| anyhow!("theme not found: {}", name))
76            .cloned()
77    }
78}
79
80impl Default for ThemeRegistry {
81    fn default() -> Self {
82        let mut this = Self {
83            themes: HashMap::default(),
84        };
85
86        this.insert_theme_families([zed_pro_family()]);
87        this.insert_user_theme_familes(crate::all_user_themes());
88
89        this
90    }
91}