1pub mod palette;
3
4pub use palette::Palette;
5
6use std::fmt;
7use std::sync::Arc;
8
9#[derive(Debug, Clone, PartialEq)]
11pub enum Theme {
12 Light,
14 Dark,
16 Dracula,
18 Nord,
20 SolarizedLight,
22 SolarizedDark,
24 GruvboxLight,
26 GruvboxDark,
28 CatppuccinLatte,
30 CatppuccinFrappe,
32 CatppuccinMacchiato,
34 CatppuccinMocha,
36 TokyoNight,
38 TokyoNightStorm,
40 TokyoNightLight,
42 KanagawaWave,
44 KanagawaDragon,
46 KanagawaLotus,
48 Moonfly,
50 Nightfly,
52 Oxocarbon,
54 Ferra,
56 Custom(Arc<Custom>),
58}
59
60impl Theme {
61 pub const ALL: &'static [Self] = &[
63 Self::Light,
64 Self::Dark,
65 Self::Dracula,
66 Self::Nord,
67 Self::SolarizedLight,
68 Self::SolarizedDark,
69 Self::GruvboxLight,
70 Self::GruvboxDark,
71 Self::CatppuccinLatte,
72 Self::CatppuccinFrappe,
73 Self::CatppuccinMacchiato,
74 Self::CatppuccinMocha,
75 Self::TokyoNight,
76 Self::TokyoNightStorm,
77 Self::TokyoNightLight,
78 Self::KanagawaWave,
79 Self::KanagawaDragon,
80 Self::KanagawaLotus,
81 Self::Moonfly,
82 Self::Nightfly,
83 Self::Oxocarbon,
84 Self::Ferra,
85 ];
86
87 pub fn custom(name: String, palette: Palette) -> Self {
89 Self::custom_with_fn(name, palette, palette::Extended::generate)
90 }
91
92 pub fn custom_with_fn(
95 name: String,
96 palette: Palette,
97 generate: impl FnOnce(Palette) -> palette::Extended,
98 ) -> Self {
99 Self::Custom(Arc::new(Custom::with_fn(name, palette, generate)))
100 }
101
102 pub fn palette(&self) -> Palette {
104 match self {
105 Self::Light => Palette::LIGHT,
106 Self::Dark => Palette::DARK,
107 Self::Dracula => Palette::DRACULA,
108 Self::Nord => Palette::NORD,
109 Self::SolarizedLight => Palette::SOLARIZED_LIGHT,
110 Self::SolarizedDark => Palette::SOLARIZED_DARK,
111 Self::GruvboxLight => Palette::GRUVBOX_LIGHT,
112 Self::GruvboxDark => Palette::GRUVBOX_DARK,
113 Self::CatppuccinLatte => Palette::CATPPUCCIN_LATTE,
114 Self::CatppuccinFrappe => Palette::CATPPUCCIN_FRAPPE,
115 Self::CatppuccinMacchiato => Palette::CATPPUCCIN_MACCHIATO,
116 Self::CatppuccinMocha => Palette::CATPPUCCIN_MOCHA,
117 Self::TokyoNight => Palette::TOKYO_NIGHT,
118 Self::TokyoNightStorm => Palette::TOKYO_NIGHT_STORM,
119 Self::TokyoNightLight => Palette::TOKYO_NIGHT_LIGHT,
120 Self::KanagawaWave => Palette::KANAGAWA_WAVE,
121 Self::KanagawaDragon => Palette::KANAGAWA_DRAGON,
122 Self::KanagawaLotus => Palette::KANAGAWA_LOTUS,
123 Self::Moonfly => Palette::MOONFLY,
124 Self::Nightfly => Palette::NIGHTFLY,
125 Self::Oxocarbon => Palette::OXOCARBON,
126 Self::Ferra => Palette::FERRA,
127 Self::Custom(custom) => custom.palette,
128 }
129 }
130
131 pub fn extended_palette(&self) -> &palette::Extended {
133 match self {
134 Self::Light => &palette::EXTENDED_LIGHT,
135 Self::Dark => &palette::EXTENDED_DARK,
136 Self::Dracula => &palette::EXTENDED_DRACULA,
137 Self::Nord => &palette::EXTENDED_NORD,
138 Self::SolarizedLight => &palette::EXTENDED_SOLARIZED_LIGHT,
139 Self::SolarizedDark => &palette::EXTENDED_SOLARIZED_DARK,
140 Self::GruvboxLight => &palette::EXTENDED_GRUVBOX_LIGHT,
141 Self::GruvboxDark => &palette::EXTENDED_GRUVBOX_DARK,
142 Self::CatppuccinLatte => &palette::EXTENDED_CATPPUCCIN_LATTE,
143 Self::CatppuccinFrappe => &palette::EXTENDED_CATPPUCCIN_FRAPPE,
144 Self::CatppuccinMacchiato => {
145 &palette::EXTENDED_CATPPUCCIN_MACCHIATO
146 }
147 Self::CatppuccinMocha => &palette::EXTENDED_CATPPUCCIN_MOCHA,
148 Self::TokyoNight => &palette::EXTENDED_TOKYO_NIGHT,
149 Self::TokyoNightStorm => &palette::EXTENDED_TOKYO_NIGHT_STORM,
150 Self::TokyoNightLight => &palette::EXTENDED_TOKYO_NIGHT_LIGHT,
151 Self::KanagawaWave => &palette::EXTENDED_KANAGAWA_WAVE,
152 Self::KanagawaDragon => &palette::EXTENDED_KANAGAWA_DRAGON,
153 Self::KanagawaLotus => &palette::EXTENDED_KANAGAWA_LOTUS,
154 Self::Moonfly => &palette::EXTENDED_MOONFLY,
155 Self::Nightfly => &palette::EXTENDED_NIGHTFLY,
156 Self::Oxocarbon => &palette::EXTENDED_OXOCARBON,
157 Self::Ferra => &palette::EXTENDED_FERRA,
158 Self::Custom(custom) => &custom.extended,
159 }
160 }
161}
162
163#[allow(clippy::derivable_impls)]
164impl Default for Theme {
165 fn default() -> Self {
166 #[cfg(feature = "auto-detect-theme")]
167 {
168 use once_cell::sync::Lazy;
169
170 static DEFAULT: Lazy<Theme> =
171 Lazy::new(|| match dark_light::detect() {
172 dark_light::Mode::Dark => Theme::Dark,
173 dark_light::Mode::Light | dark_light::Mode::Default => {
174 Theme::Light
175 }
176 });
177
178 DEFAULT.clone()
179 }
180
181 #[cfg(not(feature = "auto-detect-theme"))]
182 Theme::Light
183 }
184}
185
186impl fmt::Display for Theme {
187 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
188 match self {
189 Self::Light => write!(f, "Light"),
190 Self::Dark => write!(f, "Dark"),
191 Self::Dracula => write!(f, "Dracula"),
192 Self::Nord => write!(f, "Nord"),
193 Self::SolarizedLight => write!(f, "Solarized Light"),
194 Self::SolarizedDark => write!(f, "Solarized Dark"),
195 Self::GruvboxLight => write!(f, "Gruvbox Light"),
196 Self::GruvboxDark => write!(f, "Gruvbox Dark"),
197 Self::CatppuccinLatte => write!(f, "Catppuccin Latte"),
198 Self::CatppuccinFrappe => write!(f, "Catppuccin Frappé"),
199 Self::CatppuccinMacchiato => write!(f, "Catppuccin Macchiato"),
200 Self::CatppuccinMocha => write!(f, "Catppuccin Mocha"),
201 Self::TokyoNight => write!(f, "Tokyo Night"),
202 Self::TokyoNightStorm => write!(f, "Tokyo Night Storm"),
203 Self::TokyoNightLight => write!(f, "Tokyo Night Light"),
204 Self::KanagawaWave => write!(f, "Kanagawa Wave"),
205 Self::KanagawaDragon => write!(f, "Kanagawa Dragon"),
206 Self::KanagawaLotus => write!(f, "Kanagawa Lotus"),
207 Self::Moonfly => write!(f, "Moonfly"),
208 Self::Nightfly => write!(f, "Nightfly"),
209 Self::Oxocarbon => write!(f, "Oxocarbon"),
210 Self::Ferra => write!(f, "Ferra"),
211 Self::Custom(custom) => custom.fmt(f),
212 }
213 }
214}
215
216#[derive(Debug, Clone, PartialEq)]
218pub struct Custom {
219 name: String,
220 palette: Palette,
221 extended: palette::Extended,
222}
223
224impl Custom {
225 pub fn new(name: String, palette: Palette) -> Self {
227 Self::with_fn(name, palette, palette::Extended::generate)
228 }
229
230 pub fn with_fn(
233 name: String,
234 palette: Palette,
235 generate: impl FnOnce(Palette) -> palette::Extended,
236 ) -> Self {
237 Self {
238 name,
239 palette,
240 extended: generate(palette),
241 }
242 }
243}
244
245impl fmt::Display for Custom {
246 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
247 write!(f, "{}", self.name)
248 }
249}