two_face/theme/
mod.rs

1//! Contains extra theme definitions and the [`LazyThemeSet`] type
2//!
3//! The extra themes are provided in an [`EmbeddedLazyThemeSet`] which is just a newtype around a
4//! [`LazyThemeSet`], but with an exhastive enumeration of its themes through the
5//! [`EmbeddedThemeName`] enum
6//!
7//! _Note: For visual examples of all of the embedded themes look at the docs for
8//! [`EmbeddedThemeName`]_
9
10mod core_types;
11
12use std::{fmt, ops::Index};
13
14pub use core_types::LazyThemeSet;
15
16use syntect::highlighting::{Theme, ThemeSet};
17
18/// Returns an [`EmbeddedLazyThemeSet`] with more popular theme definitions
19///
20/// These themes cover a variety of use-cases, so it's very likely that you'll only want to expose
21/// a subset or tweak the values for specific themes depending on your usage. E.g.
22/// `EmbeddedThemeName::{Ansi, Base16, Base16_256}` are all terminal related themes,
23/// `EmbeddedThemeName::InspiredGithub` uses a full-white background which wouldn't be a good fit
24/// for a static site generator, etc.
25///
26/// # Example
27///
28/// ```
29/// use two_face::theme::{extra, EmbeddedThemeName};
30///
31/// let theme_set = extra();
32/// let nord = theme_set.get(EmbeddedThemeName::Nord);
33/// ```
34pub fn extra() -> EmbeddedLazyThemeSet {
35    let theme_set =
36        syntect::dumps::from_uncompressed_data(include_bytes!("../../generated/themes.bin"))
37            .unwrap();
38    EmbeddedLazyThemeSet(theme_set)
39}
40
41/// A [`LazyThemeSet`] where we know all of the themes that are included
42pub struct EmbeddedLazyThemeSet(LazyThemeSet);
43
44impl EmbeddedLazyThemeSet {
45    /// Gets a single theme from the set
46    ///
47    /// An infallible version of [`LazyThemeSet::get()`]
48    ///
49    /// # Example
50    ///
51    /// ```
52    /// use two_face::theme::{extra, EmbeddedThemeName};
53    ///
54    /// let theme_set = extra();
55    /// // Loads the theme
56    /// let nord1 = theme_set.get(EmbeddedThemeName::Nord);
57    /// // Reuses the same loaded theme
58    /// let nord2 = theme_set.get(EmbeddedThemeName::Nord);
59    /// ```
60    pub fn get(&self, name: EmbeddedThemeName) -> &Theme {
61        self.0.get(name.as_name()).unwrap()
62    }
63
64    /// A listing of all the themes included in [`EmbeddedLazyThemeSet`]
65    ///
66    /// # Example
67    ///
68    /// ```
69    /// use two_face::theme::{EmbeddedThemeName, EmbeddedLazyThemeSet};
70    ///
71    /// // Nord should be included
72    /// assert!(EmbeddedLazyThemeSet::theme_names().contains(&EmbeddedThemeName::Nord));
73    /// ```
74    pub fn theme_names() -> &'static [EmbeddedThemeName] {
75        &[
76            EmbeddedThemeName::Ansi,
77            EmbeddedThemeName::Base16,
78            EmbeddedThemeName::Base16EightiesDark,
79            EmbeddedThemeName::Base16MochaDark,
80            EmbeddedThemeName::Base16OceanDark,
81            EmbeddedThemeName::Base16OceanLight,
82            EmbeddedThemeName::Base16_256,
83            EmbeddedThemeName::CatppuccinFrappe,
84            EmbeddedThemeName::CatppuccinLatte,
85            EmbeddedThemeName::CatppuccinMacchiato,
86            EmbeddedThemeName::CatppuccinMocha,
87            EmbeddedThemeName::ColdarkCold,
88            EmbeddedThemeName::ColdarkDark,
89            EmbeddedThemeName::DarkNeon,
90            EmbeddedThemeName::Dracula,
91            EmbeddedThemeName::Github,
92            EmbeddedThemeName::GruvboxDark,
93            EmbeddedThemeName::GruvboxLight,
94            EmbeddedThemeName::InspiredGithub,
95            EmbeddedThemeName::Leet,
96            EmbeddedThemeName::MonokaiExtended,
97            EmbeddedThemeName::MonokaiExtendedBright,
98            EmbeddedThemeName::MonokaiExtendedLight,
99            EmbeddedThemeName::MonokaiExtendedOrigin,
100            EmbeddedThemeName::Nord,
101            EmbeddedThemeName::OneHalfDark,
102            EmbeddedThemeName::OneHalfLight,
103            EmbeddedThemeName::SolarizedDark,
104            EmbeddedThemeName::SolarizedLight,
105            EmbeddedThemeName::SublimeSnazzy,
106            EmbeddedThemeName::TwoDark,
107            EmbeddedThemeName::Zenburn,
108        ]
109    }
110}
111
112impl From<EmbeddedLazyThemeSet> for LazyThemeSet {
113    fn from(embedded: EmbeddedLazyThemeSet) -> Self {
114        embedded.0
115    }
116}
117
118impl From<&EmbeddedLazyThemeSet> for ThemeSet {
119    fn from(embedded: &EmbeddedLazyThemeSet) -> Self {
120        Self::from(&embedded.0)
121    }
122}
123
124impl From<EmbeddedLazyThemeSet> for ThemeSet {
125    fn from(embedded: EmbeddedLazyThemeSet) -> Self {
126        (&embedded).into()
127    }
128}
129
130impl Index<EmbeddedThemeName> for EmbeddedLazyThemeSet {
131    type Output = Theme;
132
133    fn index(&self, theme_name: EmbeddedThemeName) -> &Self::Output {
134        self.get(theme_name)
135    }
136}
137
138// NOTE: doc comment HTML is copied from the tests/docs_watchdog/theme.rs tests
139/// An enum that represents all themes included in [`EmbeddedLazyThemeSet`]
140///
141/// A demo is included for how each theme highlights the following Elixir snippet
142///
143/// ```elixir
144/// There currently is no ternary operator like  true ? "yes" : "no"
145/// # So the following is suggested
146/// "no" = if 1 == 0, do: "yes", else: "no"
147/// ```
148#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
149#[cfg_attr(test, derive(strum::EnumIter))]
150pub enum EmbeddedThemeName {
151    /// ANSI
152    ///
153    /// _Doesn't display as HTML well_
154    Ansi,
155    /// Base16
156    ///
157    /// _Doesn't display as HTML well_
158    Base16,
159    /// Base16 Eighties Dark
160    ///
161    /// <pre style="background-color:#2d2d2d;">
162    /// <span style="color:#747369;"># There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
163    /// </span><span style="color:#747369;"># So the following is suggested
164    /// </span><span style="color:#d3d0c8;">&quot;</span><span style="color:#99cc99;">no</span><span style="color:#d3d0c8;">&quot; = </span><span style="color:#cc99cc;">if </span><span style="color:#f99157;">1 </span><span style="color:#d3d0c8;">== </span><span style="color:#f99157;">0</span><span style="color:#d3d0c8;">, </span><span style="color:#f99157;">do: </span><span style="color:#d3d0c8;">&quot;</span><span style="color:#99cc99;">yes</span><span style="color:#d3d0c8;">&quot;, </span><span style="color:#f99157;">else: </span><span style="color:#d3d0c8;">&quot;</span><span style="color:#99cc99;">no</span><span style="color:#d3d0c8;">&quot;
165    /// </span></pre>
166    Base16EightiesDark,
167    /// Base16 Mocha Dark Theme
168    ///
169    /// <pre style="background-color:#3b3228;">
170    /// <span style="color:#7e705a;"># There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
171    /// </span><span style="color:#7e705a;"># So the following is suggested
172    /// </span><span style="color:#d0c8c6;">&quot;</span><span style="color:#beb55b;">no</span><span style="color:#d0c8c6;">&quot; = </span><span style="color:#a89bb9;">if </span><span style="color:#d28b71;">1 </span><span style="color:#d0c8c6;">== </span><span style="color:#d28b71;">0</span><span style="color:#d0c8c6;">, </span><span style="color:#d28b71;">do: </span><span style="color:#d0c8c6;">&quot;</span><span style="color:#beb55b;">yes</span><span style="color:#d0c8c6;">&quot;, </span><span style="color:#d28b71;">else: </span><span style="color:#d0c8c6;">&quot;</span><span style="color:#beb55b;">no</span><span style="color:#d0c8c6;">&quot;
173    /// </span></pre>
174    Base16MochaDark,
175    /// Base16 Ocean Dark
176    ///
177    /// <pre style="background-color:#2b303b;">
178    /// <span style="color:#65737e;"># There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
179    /// </span><span style="color:#65737e;"># So the following is suggested
180    /// </span><span style="color:#c0c5ce;">&quot;</span><span style="color:#a3be8c;">no</span><span style="color:#c0c5ce;">&quot; = </span><span style="color:#b48ead;">if </span><span style="color:#d08770;">1 </span><span style="color:#c0c5ce;">== </span><span style="color:#d08770;">0</span><span style="color:#c0c5ce;">, </span><span style="color:#d08770;">do: </span><span style="color:#c0c5ce;">&quot;</span><span style="color:#a3be8c;">yes</span><span style="color:#c0c5ce;">&quot;, </span><span style="color:#d08770;">else: </span><span style="color:#c0c5ce;">&quot;</span><span style="color:#a3be8c;">no</span><span style="color:#c0c5ce;">&quot;
181    /// </span></pre>
182    Base16OceanDark,
183    /// Base16 Ocean Light
184    ///
185    /// <pre style="background-color:#eff1f5;">
186    /// <span style="color:#a7adba;"># There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
187    /// </span><span style="color:#a7adba;"># So the following is suggested
188    /// </span><span style="color:#4f5b66;">&quot;</span><span style="color:#a3be8c;">no</span><span style="color:#4f5b66;">&quot; = </span><span style="color:#b48ead;">if </span><span style="color:#d08770;">1 </span><span style="color:#4f5b66;">== </span><span style="color:#d08770;">0</span><span style="color:#4f5b66;">, </span><span style="color:#d08770;">do: </span><span style="color:#4f5b66;">&quot;</span><span style="color:#a3be8c;">yes</span><span style="color:#4f5b66;">&quot;, </span><span style="color:#d08770;">else: </span><span style="color:#4f5b66;">&quot;</span><span style="color:#a3be8c;">no</span><span style="color:#4f5b66;">&quot;
189    /// </span></pre>
190    Base16OceanLight,
191    /// Base16 256
192    ///
193    /// _Doesn't display as HTML well_
194    Base16_256,
195    /// Catppuccin Frappe
196    ///
197    /// <pre style="background-color:#303446;">
198    /// <span style="font-style:italic;color:#7c7f93;"># There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
199    /// </span><span style="font-style:italic;color:#7c7f93;"># So the following is suggested
200    /// </span><span style="color:#a6d189;">&quot;</span><span style="color:#a6d189;">no</span><span style="color:#a6d189;">&quot;</span><span style="color:#c6d0f5;"> </span><span style="color:#81c8be;">=</span><span style="color:#c6d0f5;"> </span><span style="color:#ca9ee6;">if</span><span style="color:#c6d0f5;"> </span><span style="color:#ef9f76;">1</span><span style="color:#c6d0f5;"> </span><span style="color:#81c8be;">==</span><span style="color:#c6d0f5;"> </span><span style="color:#ef9f76;">0</span><span style="color:#949cbb;">,</span><span style="color:#c6d0f5;"> </span><span style="color:#c6d0f5;">do</span><span style="color:#949cbb;">:</span><span style="color:#c6d0f5;"> </span><span style="color:#a6d189;">&quot;</span><span style="color:#a6d189;">yes</span><span style="color:#a6d189;">&quot;</span><span style="color:#949cbb;">,</span><span style="color:#c6d0f5;"> </span><span style="color:#c6d0f5;">else</span><span style="color:#949cbb;">:</span><span style="color:#c6d0f5;"> </span><span style="color:#a6d189;">&quot;</span><span style="color:#a6d189;">no</span><span style="color:#a6d189;">&quot;
201    /// </span></pre>
202    CatppuccinFrappe,
203    /// Catppuccin Latte
204    ///
205    /// <pre style="background-color:#eff1f5;">
206    /// <span style="font-style:italic;color:#7c7f93;"># There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
207    /// </span><span style="font-style:italic;color:#7c7f93;"># So the following is suggested
208    /// </span><span style="color:#40a02b;">&quot;no&quot; </span><span style="color:#179299;">= </span><span style="color:#8839ef;">if </span><span style="color:#fe640b;">1 </span><span style="color:#179299;">== </span><span style="color:#fe640b;">0</span><span style="color:#7c7f93;">, </span><span style="color:#4c4f69;">do</span><span style="color:#7c7f93;">: </span><span style="color:#40a02b;">&quot;yes&quot;</span><span style="color:#7c7f93;">, </span><span style="color:#4c4f69;">else</span><span style="color:#7c7f93;">: </span><span style="color:#40a02b;">&quot;no&quot;
209    /// </span></pre>
210    CatppuccinLatte,
211    /// Catppuccin Macchiato
212    ///
213    /// <pre style="background-color:#24273a;">
214    /// <span style="font-style:italic;color:#939ab7;"># There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
215    /// </span><span style="font-style:italic;color:#939ab7;"># So the following is suggested
216    /// </span><span style="color:#a6da95;">&quot;no&quot; </span><span style="color:#8bd5ca;">= </span><span style="color:#c6a0f6;">if </span><span style="color:#f5a97f;">1 </span><span style="color:#8bd5ca;">== </span><span style="color:#f5a97f;">0</span><span style="color:#939ab7;">, </span><span style="color:#cad3f5;">do</span><span style="color:#939ab7;">: </span><span style="color:#a6da95;">&quot;yes&quot;</span><span style="color:#939ab7;">, </span><span style="color:#cad3f5;">else</span><span style="color:#939ab7;">: </span><span style="color:#a6da95;">&quot;no&quot;
217    /// </span></pre>
218    CatppuccinMacchiato,
219    /// Catppuccin Mocha
220    ///
221    /// <pre style="background-color:#1e1e2e;">
222    /// <span style="font-style:italic;color:#6c7086;"># There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
223    /// </span><span style="font-style:italic;color:#6c7086;"># So the following is suggested
224    /// </span><span style="color:#a6e3a1;">&quot;no&quot; </span><span style="color:#94e2d5;">= </span><span style="color:#cba6f7;">if </span><span style="color:#fab387;">1 </span><span style="color:#94e2d5;">== </span><span style="color:#fab387;">0</span><span style="color:#9399b2;">, </span><span style="color:#cdd6f4;">do</span><span style="color:#9399b2;">: </span><span style="color:#a6e3a1;">&quot;yes&quot;</span><span style="color:#9399b2;">, </span><span style="color:#cdd6f4;">else</span><span style="color:#9399b2;">: </span><span style="color:#a6e3a1;">&quot;no&quot;
225    /// </span></pre>
226    CatppuccinMocha,
227    /// Coldark-Cold
228    ///
229    /// <pre style="background-color:#e3eaf2;">
230    /// <span style="color:#3c526d;"># There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
231    /// </span><span style="color:#3c526d;"># So the following is suggested
232    /// </span><span style="color:#116b00;">&quot;no&quot; </span><span style="color:#a04900;">= if </span><span style="color:#755f00;">1 </span><span style="color:#a04900;">== </span><span style="color:#755f00;">0</span><span style="color:#111b27;">, </span><span style="color:#005a8e;">do</span><span style="color:#111b27;">: </span><span style="color:#116b00;">&quot;yes&quot;</span><span style="color:#111b27;">, </span><span style="color:#005a8e;">else</span><span style="color:#111b27;">: </span><span style="color:#116b00;">&quot;no&quot;
233    /// </span></pre>
234    ColdarkCold,
235    /// Coldark-Dark
236    ///
237    /// <pre style="background-color:#111b27;">
238    /// <span style="color:#8da1b9;"># There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
239    /// </span><span style="color:#8da1b9;"># So the following is suggested
240    /// </span><span style="color:#91d076;">&quot;no&quot; </span><span style="color:#e9ae7e;">= if </span><span style="color:#e6d37a;">1 </span><span style="color:#e9ae7e;">== </span><span style="color:#e6d37a;">0</span><span style="color:#e3eaf2;">, </span><span style="color:#6cb8e6;">do</span><span style="color:#e3eaf2;">: </span><span style="color:#91d076;">&quot;yes&quot;</span><span style="color:#e3eaf2;">, </span><span style="color:#6cb8e6;">else</span><span style="color:#e3eaf2;">: </span><span style="color:#91d076;">&quot;no&quot;
241    /// </span></pre>
242    ColdarkDark,
243    /// Dark Neon
244    ///
245    /// <pre style="background-color:#000000;">
246    /// <span style="background-color:#212121;color:#7c7c7c;"># There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
247    /// </span><span style="background-color:#212121;color:#7c7c7c;"># So the following is suggested
248    /// </span><span style="color:#ccff66;">&quot;no&quot; </span><span style="color:#aaaaaa;">= </span><span style="color:#66ccff;">if </span><span style="font-weight:bold;color:#ff73fd;">1 </span><span style="color:#aaaaaa;">== </span><span style="font-weight:bold;color:#ff73fd;">0</span><span style="color:#ffffff;">, </span><span style="color:#99cc99;">do: </span><span style="color:#ccff66;">&quot;yes&quot;</span><span style="color:#ffffff;">, </span><span style="color:#99cc99;">else: </span><span style="color:#ccff66;">&quot;no&quot;
249    /// </span></pre>
250    DarkNeon,
251    /// Dracula
252    ///
253    /// <pre style="background-color:#282a36;">
254    /// <span style="color:#6272a4;"># There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
255    /// </span><span style="color:#6272a4;"># So the following is suggested
256    /// </span><span style="color:#f1fa8c;">&quot;no&quot; </span><span style="color:#ff79c6;">= if </span><span style="color:#bd93f9;">1 </span><span style="color:#ff79c6;">== </span><span style="color:#bd93f9;">0</span><span style="color:#f8f8f2;">, </span><span style="color:#bd93f9;">do: </span><span style="color:#f1fa8c;">&quot;yes&quot;</span><span style="color:#f8f8f2;">, </span><span style="color:#bd93f9;">else: </span><span style="color:#f1fa8c;">&quot;no&quot;
257    /// </span></pre>
258    Dracula,
259    /// GitHub
260    ///
261    /// <pre style="background-color:#ffffff;">
262    /// <span style="color:#969896;"># There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
263    /// </span><span style="color:#969896;"># So the following is suggested
264    /// </span><span style="color:#183691;">&quot;no&quot; </span><span style="color:#a71d5d;">= if </span><span style="color:#0086b3;">1 </span><span style="color:#a71d5d;">== </span><span style="color:#0086b3;">0</span><span style="color:#333333;">, </span><span style="color:#0086b3;">do: </span><span style="color:#183691;">&quot;yes&quot;</span><span style="color:#333333;">, </span><span style="color:#0086b3;">else: </span><span style="color:#183691;">&quot;no&quot;
265    /// </span></pre>
266    Github,
267    /// gruvbox (Dark)
268    ///
269    /// <pre style="background-color:#282828;">
270    /// <span style="font-style:italic;color:#928374;"># There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
271    /// </span><span style="font-style:italic;color:#928374;"># So the following is suggested
272    /// </span><span style="color:#fbf1c7;">&quot;</span><span style="color:#b8bb26;">no</span><span style="color:#fbf1c7;">&quot; </span><span style="color:#8ec07c;">= </span><span style="color:#fb4934;">if </span><span style="color:#d3869b;">1 </span><span style="color:#8ec07c;">== </span><span style="color:#d3869b;">0</span><span style="color:#fbf1c7;">, </span><span style="color:#d3869b;">do</span><span style="color:#fbf1c7;">: &quot;</span><span style="color:#b8bb26;">yes</span><span style="color:#fbf1c7;">&quot;, </span><span style="color:#d3869b;">else</span><span style="color:#fbf1c7;">: &quot;</span><span style="color:#b8bb26;">no</span><span style="color:#fbf1c7;">&quot;
273    /// </span></pre>
274    GruvboxDark,
275    /// gruvbox (Light)
276    ///
277    /// <pre style="background-color:#fbf1c7;">
278    /// <span style="font-style:italic;color:#928374;"># There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
279    /// </span><span style="font-style:italic;color:#928374;"># So the following is suggested
280    /// </span><span style="color:#282828;">&quot;</span><span style="color:#79740e;">no</span><span style="color:#282828;">&quot; </span><span style="color:#427b58;">= </span><span style="color:#9d0006;">if </span><span style="color:#8f3f71;">1 </span><span style="color:#427b58;">== </span><span style="color:#8f3f71;">0</span><span style="color:#282828;">, </span><span style="color:#8f3f71;">do</span><span style="color:#282828;">: &quot;</span><span style="color:#79740e;">yes</span><span style="color:#282828;">&quot;, </span><span style="color:#8f3f71;">else</span><span style="color:#282828;">: &quot;</span><span style="color:#79740e;">no</span><span style="color:#282828;">&quot;
281    /// </span></pre>
282    GruvboxLight,
283    /// Inspired GitHub
284    ///
285    /// <pre style="background-color:#ffffff;">
286    /// <span style="font-style:italic;color:#969896;"># There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
287    /// </span><span style="font-style:italic;color:#969896;"># So the following is suggested
288    /// </span><span style="color:#183691;">&quot;no&quot; </span><span style="font-weight:bold;color:#a71d5d;">= if </span><span style="color:#0086b3;">1 </span><span style="font-weight:bold;color:#a71d5d;">== </span><span style="color:#0086b3;">0</span><span style="color:#323232;">, </span><span style="color:#0086b3;">do: </span><span style="color:#183691;">&quot;yes&quot;</span><span style="color:#323232;">, </span><span style="color:#0086b3;">else: </span><span style="color:#183691;">&quot;no&quot;
289    /// </span></pre>
290    InspiredGithub,
291    /// 1337
292    ///
293    /// <pre style="background-color:#191919;">
294    /// <span style="color:#6d6d6d;"># There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
295    /// </span><span style="color:#6d6d6d;"># So the following is suggested
296    /// </span><span style="color:#ffffff;">&quot;</span><span style="color:#fbe3bf;">no</span><span style="color:#ffffff;">&quot; </span><span style="color:#ff5e5e;">= if </span><span style="color:#fdb082;">1 </span><span style="color:#ff5e5e;">== </span><span style="color:#fdb082;">0</span><span style="color:#f8f8f2;">, </span><span style="color:#fdb082;">do: </span><span style="color:#ffffff;">&quot;</span><span style="color:#fbe3bf;">yes</span><span style="color:#ffffff;">&quot;</span><span style="color:#f8f8f2;">, </span><span style="color:#fdb082;">else: </span><span style="color:#ffffff;">&quot;</span><span style="color:#fbe3bf;">no</span><span style="color:#ffffff;">&quot;
297    /// </span></pre>
298    Leet,
299    /// Monokai Extended
300    ///
301    /// <pre style="background-color:#222222;">
302    /// <span style="color:#75715e;"># There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
303    /// </span><span style="color:#75715e;"># So the following is suggested
304    /// </span><span style="color:#e6db74;">&quot;no&quot; </span><span style="color:#f92672;">= if </span><span style="color:#be84ff;">1 </span><span style="color:#f92672;">== </span><span style="color:#be84ff;">0</span><span style="color:#f8f8f2;">, </span><span style="color:#be84ff;">do: </span><span style="color:#e6db74;">&quot;yes&quot;</span><span style="color:#f8f8f2;">, </span><span style="color:#be84ff;">else: </span><span style="color:#e6db74;">&quot;no&quot;
305    /// </span></pre>
306    MonokaiExtended,
307    /// Monokai Extended Bright
308    ///
309    /// <pre style="background-color:#272822;">
310    /// <span style="color:#75715e;"># There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
311    /// </span><span style="color:#75715e;"># So the following is suggested
312    /// </span><span style="color:#e6db74;">&quot;no&quot; </span><span style="color:#f92672;">= if </span><span style="color:#ae81ff;">1 </span><span style="color:#f92672;">== </span><span style="color:#ae81ff;">0</span><span style="color:#f8f8f2;">, </span><span style="color:#ae81ff;">do: </span><span style="color:#e6db74;">&quot;yes&quot;</span><span style="color:#f8f8f2;">, </span><span style="color:#ae81ff;">else: </span><span style="color:#e6db74;">&quot;no&quot;
313    /// </span></pre>
314    MonokaiExtendedBright,
315    /// Monokai Extended Light
316    ///
317    /// <pre style="background-color:#fafafa;">
318    /// <span style="color:#75715e;"># There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
319    /// </span><span style="color:#75715e;"># So the following is suggested
320    /// </span><span style="color:#998f2f;">&quot;no&quot; </span><span style="color:#f9005a;">= if </span><span style="color:#684d99;">1 </span><span style="color:#f9005a;">== </span><span style="color:#684d99;">0</span><span style="color:#49483e;">, </span><span style="color:#684d99;">do: </span><span style="color:#998f2f;">&quot;yes&quot;</span><span style="color:#49483e;">, </span><span style="color:#684d99;">else: </span><span style="color:#998f2f;">&quot;no&quot;
321    /// </span></pre>
322    MonokaiExtendedLight,
323    /// Monokai Extended Origin
324    ///
325    /// <pre style="background-color:#272822;">
326    /// <span style="color:#75715e;"># There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
327    /// </span><span style="color:#75715e;"># So the following is suggested
328    /// </span><span style="color:#e6db74;">&quot;no&quot; </span><span style="color:#f92672;">= if </span><span style="color:#ae81ff;">1 </span><span style="color:#f92672;">== </span><span style="color:#ae81ff;">0</span><span style="color:#f8f8f2;">, </span><span style="color:#ae81ff;">do: </span><span style="color:#e6db74;">&quot;yes&quot;</span><span style="color:#f8f8f2;">, </span><span style="color:#ae81ff;">else: </span><span style="color:#e6db74;">&quot;no&quot;
329    /// </span></pre>
330    MonokaiExtendedOrigin,
331    /// Nord
332    ///
333    /// <pre style="background-color:#2e3440;">
334    /// <span style="color:#616e88;"># There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
335    /// </span><span style="color:#616e88;"># So the following is suggested
336    /// </span><span style="color:#a3be8c;">&quot;no&quot; </span><span style="color:#81a1c1;">= if </span><span style="color:#b48ead;">1 </span><span style="color:#81a1c1;">== </span><span style="color:#b48ead;">0</span><span style="color:#eceff4;">, </span><span style="color:#d8dee9;">do: </span><span style="color:#a3be8c;">&quot;yes&quot;</span><span style="color:#eceff4;">, </span><span style="color:#d8dee9;">else: </span><span style="color:#a3be8c;">&quot;no&quot;
337    /// </span></pre>
338    Nord,
339    /// One Half Dark
340    ///
341    /// <pre style="background-color:#282c34;">
342    /// <span style="color:#5c6370;"># There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
343    /// </span><span style="color:#5c6370;"># So the following is suggested
344    /// </span><span style="color:#98c379;">&quot;no&quot; </span><span style="color:#c678dd;">= if </span><span style="color:#e5c07b;">1 </span><span style="color:#c678dd;">== </span><span style="color:#e5c07b;">0</span><span style="color:#dcdfe4;">, </span><span style="color:#e5c07b;">do: </span><span style="color:#98c379;">&quot;yes&quot;</span><span style="color:#dcdfe4;">, </span><span style="color:#e5c07b;">else: </span><span style="color:#98c379;">&quot;no&quot;
345    /// </span></pre>
346    OneHalfDark,
347    /// One Half Light
348    ///
349    /// <pre style="background-color:#fafafa;">
350    /// <span style="color:#a0a1a7;"># There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
351    /// </span><span style="color:#a0a1a7;"># So the following is suggested
352    /// </span><span style="color:#50a14f;">&quot;no&quot; </span><span style="color:#a626a4;">= if </span><span style="color:#c18401;">1 </span><span style="color:#a626a4;">== </span><span style="color:#c18401;">0</span><span style="color:#383a42;">, </span><span style="color:#c18401;">do: </span><span style="color:#50a14f;">&quot;yes&quot;</span><span style="color:#383a42;">, </span><span style="color:#c18401;">else: </span><span style="color:#50a14f;">&quot;no&quot;
353    /// </span></pre>
354    OneHalfLight,
355    /// Solarized (dark)
356    ///
357    /// <pre style="background-color:#002b36;">
358    /// <span style="color:#586e75;"># There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
359    /// </span><span style="color:#586e75;"># So the following is suggested
360    /// </span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">no</span><span style="color:#839496;">&quot; </span><span style="color:#657b83;">= </span><span style="color:#859900;">if </span><span style="color:#6c71c4;">1 </span><span style="color:#657b83;">== </span><span style="color:#6c71c4;">0</span><span style="color:#839496;">, </span><span style="color:#cb4b16;">do: </span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">yes</span><span style="color:#839496;">&quot;, </span><span style="color:#cb4b16;">else: </span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">no</span><span style="color:#839496;">&quot;
361    /// </span></pre>
362    SolarizedDark,
363    /// Solarized (light)
364    ///
365    /// <pre style="background-color:#fdf6e3;">
366    /// <span style="color:#93a1a1;"># There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
367    /// </span><span style="color:#93a1a1;"># So the following is suggested
368    /// </span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">no</span><span style="color:#839496;">&quot; </span><span style="color:#657b83;">= </span><span style="color:#859900;">if </span><span style="color:#6c71c4;">1 </span><span style="color:#657b83;">== </span><span style="color:#6c71c4;">0</span><span style="color:#657b83;">, </span><span style="color:#cb4b16;">do: </span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">yes</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">, </span><span style="color:#cb4b16;">else: </span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">no</span><span style="color:#839496;">&quot;
369    /// </span></pre>
370    SolarizedLight,
371    /// Sublime Snazzy
372    ///
373    /// <pre style="background-color:#282a36;">
374    /// <span style="color:#686868;"># There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
375    /// </span><span style="color:#686868;"># So the following is suggested
376    /// </span><span style="color:#f3f99d;">&quot;no&quot; </span><span style="color:#ff5c57;">= if </span><span style="color:#f1f1f0;">1 </span><span style="color:#ff5c57;">== </span><span style="color:#f1f1f0;">0</span><span style="color:#f8f8f2;">, </span><span style="color:#5af78e;">do: </span><span style="color:#f3f99d;">&quot;yes&quot;</span><span style="color:#f8f8f2;">, </span><span style="color:#5af78e;">else: </span><span style="color:#f3f99d;">&quot;no&quot;
377    /// </span></pre>
378    SublimeSnazzy,
379    /// TwoDark
380    ///
381    /// <pre style="background-color:#282c34;">
382    /// <span style="font-style:italic;color:#5c6370;"># There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
383    /// </span><span style="font-style:italic;color:#5c6370;"># So the following is suggested
384    /// </span><span style="color:#98c379;">&quot;no&quot; </span><span style="color:#abb2bf;">= </span><span style="color:#c678dd;">if </span><span style="color:#d19a66;">1 </span><span style="color:#abb2bf;">== </span><span style="color:#d19a66;">0</span><span style="color:#abb2bf;">, </span><span style="color:#d19a66;">do: </span><span style="color:#98c379;">&quot;yes&quot;</span><span style="color:#abb2bf;">, </span><span style="color:#d19a66;">else: </span><span style="color:#98c379;">&quot;no&quot;
385    /// </span></pre>
386    TwoDark,
387    /// zenburn
388    ///
389    /// <pre style="background-color:#3f3f3f;">
390    /// <span style="color:#a0cfa1;">#</span><span style="color:#87ae86;"> There currently is no ternary operator like  true ? &quot;yes&quot; : &quot;no&quot;
391    /// </span><span style="color:#a0cfa1;">#</span><span style="color:#87ae86;"> So the following is suggested
392    /// </span><span style="color:#d6d6d680;">&quot;</span><span style="color:#d68686;">no</span><span style="color:#d6d6d680;">&quot; </span><span style="color:#ececec;">= </span><span style="color:#fed6af;">if </span><span style="color:#87d6d5;">1 </span><span style="color:#ececec;">== </span><span style="color:#87d6d5;">0</span><span style="color:#dedede;">, </span><span style="color:#cc9495;">do: </span><span style="color:#d6d6d680;">&quot;</span><span style="color:#d68686;">yes</span><span style="color:#d6d6d680;">&quot;</span><span style="color:#dedede;">, </span><span style="color:#cc9495;">else: </span><span style="color:#d6d6d680;">&quot;</span><span style="color:#d68686;">no</span><span style="color:#d6d6d680;">&quot;
393    /// </span></pre>
394    Zenburn,
395}
396
397impl EmbeddedThemeName {
398    /// The name of each embedded theme
399    ///
400    /// This matches the key used for each theme in [`ThemeSet`]'s `themes`
401    ///
402    /// ```
403    /// use two_face::theme::EmbeddedThemeName;
404    ///
405    /// assert_eq!(
406    ///     EmbeddedThemeName::Leet.as_name(),
407    ///     "1337",
408    /// );
409    /// // `.as_name()` is used for `Display` too!
410    /// assert_eq!(
411    ///     EmbeddedThemeName::SolarizedDark.to_string(),
412    ///     "Solarized (dark)",
413    /// );
414    /// ```
415    pub fn as_name(self) -> &'static str {
416        match self {
417            Self::Ansi => "ansi",
418            Self::Base16 => "base16",
419            Self::Base16EightiesDark => "base16-eighties.dark",
420            Self::Base16MochaDark => "base16-mocha.dark",
421            Self::Base16OceanDark => "base16-ocean.dark",
422            Self::Base16OceanLight => "base16-ocean.light",
423            Self::Base16_256 => "base16-256",
424            Self::CatppuccinFrappe => "Catppuccin Frappe",
425            Self::CatppuccinLatte => "Catppuccin Latte",
426            Self::CatppuccinMacchiato => "Catppuccin Macchiato",
427            Self::CatppuccinMocha => "Catppuccin Mocha",
428            Self::ColdarkCold => "Coldark-Cold",
429            Self::ColdarkDark => "Coldark-Dark",
430            Self::DarkNeon => "DarkNeon",
431            Self::Dracula => "Dracula",
432            Self::Github => "GitHub",
433            Self::GruvboxDark => "gruvbox-dark",
434            Self::GruvboxLight => "gruvbox-light",
435            Self::InspiredGithub => "InspiredGitHub",
436            Self::Leet => "1337",
437            Self::MonokaiExtended => "Monokai Extended",
438            Self::MonokaiExtendedBright => "Monokai Extended Bright",
439            Self::MonokaiExtendedLight => "Monokai Extended Light",
440            Self::MonokaiExtendedOrigin => "Monokai Extended Origin",
441            Self::Nord => "Nord",
442            Self::OneHalfDark => "OneHalfDark",
443            Self::OneHalfLight => "OneHalfLight",
444            Self::SolarizedDark => "Solarized (dark)",
445            Self::SolarizedLight => "Solarized (light)",
446            Self::SublimeSnazzy => "Sublime Snazzy",
447            Self::TwoDark => "TwoDark",
448            Self::Zenburn => "zenburn",
449        }
450    }
451}
452
453impl fmt::Display for EmbeddedThemeName {
454    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
455        f.write_str(self.as_name())
456    }
457}
458
459#[cfg(test)]
460mod tests {
461    use std::collections::BTreeSet;
462
463    use super::*;
464
465    use strum::IntoEnumIterator;
466
467    #[test]
468    fn theme_set_roundtrip() {
469        let theme_set: ThemeSet = extra().into();
470        let lazy: LazyThemeSet = (&theme_set).into();
471        let theme_set_again: ThemeSet = lazy.into();
472        let eq = theme_set
473            .themes
474            .into_iter()
475            .zip(theme_set_again.themes.into_iter())
476            .all(|(pair1, pair2)| pair1 == pair2);
477        assert!(eq);
478    }
479
480    #[test]
481    fn embedded_theme_is_exhaustive() {
482        let theme_set = extra();
483        for theme_name in EmbeddedThemeName::iter() {
484            println!("Getting: {:?}", theme_name);
485            let _ = theme_set.get(theme_name);
486        }
487
488        assert_eq!(theme_set.0.themes.len(), EmbeddedThemeName::iter().len());
489        assert_eq!(
490            EmbeddedLazyThemeSet::theme_names().len(),
491            EmbeddedThemeName::iter().len()
492        );
493
494        let all_unique: BTreeSet<_> = EmbeddedLazyThemeSet::theme_names().iter().collect();
495        assert_eq!(all_unique.len(), EmbeddedLazyThemeSet::theme_names().len());
496    }
497}