Skip to main content

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 Julia snippet adapted from the
142/// Julia _Getting Started_ manual
143///
144/// ```julia
145/// # sends a variety of values over a channel
146/// function producer(c::Channel)
147///     for n=1:4
148///         put!(c, 2n)
149///     end
150///     put!(c, "stop")
151/// end;
152/// ```
153#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
154#[cfg_attr(test, derive(strum::EnumIter))]
155pub enum EmbeddedThemeName {
156    /// ANSI
157    ///
158    /// _Doesn't display as HTML well_
159    Ansi,
160    /// Base16
161    ///
162    /// _Doesn't display as HTML well_
163    Base16,
164    /// Base16 Eighties Dark
165    ///
166    /// <pre style="background-color:#2d2d2d;">
167    /// <span style="color:#747369;"># sends a variety of values over a channel
168    /// </span><span style="color:#d3d0c8;">function producer(c::</span><span style="color:#ffcc66;">Channel</span><span style="color:#d3d0c8;">)
169    /// </span><span style="color:#d3d0c8;">    </span><span style="color:#cc99cc;">for</span><span style="color:#d3d0c8;"> n=</span><span style="color:#f99157;">1</span><span style="color:#d3d0c8;">:</span><span style="color:#f99157;">4
170    /// </span><span style="color:#d3d0c8;">        put!(c, 2n)
171    /// </span><span style="color:#d3d0c8;">    </span><span style="color:#cc99cc;">end
172    /// </span><span style="color:#d3d0c8;">    put!(c, &quot;</span><span style="color:#99cc99;">stop</span><span style="color:#d3d0c8;">&quot;)
173    /// </span><span style="color:#cc99cc;">end</span><span style="color:#d3d0c8;">;
174    /// </span></pre>
175    Base16EightiesDark,
176    /// Base16 Mocha Dark Theme
177    ///
178    /// <pre style="background-color:#3b3228;">
179    /// <span style="color:#7e705a;"># sends a variety of values over a channel
180    /// </span><span style="color:#d0c8c6;">function producer(c::</span><span style="color:#f4bc87;">Channel</span><span style="color:#d0c8c6;">)
181    /// </span><span style="color:#d0c8c6;">    </span><span style="color:#a89bb9;">for</span><span style="color:#d0c8c6;"> n=</span><span style="color:#d28b71;">1</span><span style="color:#d0c8c6;">:</span><span style="color:#d28b71;">4
182    /// </span><span style="color:#d0c8c6;">        put!(c, 2n)
183    /// </span><span style="color:#d0c8c6;">    </span><span style="color:#a89bb9;">end
184    /// </span><span style="color:#d0c8c6;">    put!(c, &quot;</span><span style="color:#beb55b;">stop</span><span style="color:#d0c8c6;">&quot;)
185    /// </span><span style="color:#a89bb9;">end</span><span style="color:#d0c8c6;">;
186    /// </span></pre>
187    Base16MochaDark,
188    /// Base16 Ocean Dark
189    ///
190    /// <pre style="background-color:#2b303b;">
191    /// <span style="color:#65737e;"># sends a variety of values over a channel
192    /// </span><span style="color:#c0c5ce;">function producer(c::</span><span style="color:#ebcb8b;">Channel</span><span style="color:#c0c5ce;">)
193    /// </span><span style="color:#c0c5ce;">    </span><span style="color:#b48ead;">for</span><span style="color:#c0c5ce;"> n=</span><span style="color:#d08770;">1</span><span style="color:#c0c5ce;">:</span><span style="color:#d08770;">4
194    /// </span><span style="color:#c0c5ce;">        put!(c, 2n)
195    /// </span><span style="color:#c0c5ce;">    </span><span style="color:#b48ead;">end
196    /// </span><span style="color:#c0c5ce;">    put!(c, &quot;</span><span style="color:#a3be8c;">stop</span><span style="color:#c0c5ce;">&quot;)
197    /// </span><span style="color:#b48ead;">end</span><span style="color:#c0c5ce;">;
198    /// </span></pre>
199    Base16OceanDark,
200    /// Base16 Ocean Light
201    ///
202    /// <pre style="background-color:#eff1f5;">
203    /// <span style="color:#a7adba;"># sends a variety of values over a channel
204    /// </span><span style="color:#4f5b66;">function producer(c::</span><span style="color:#d08770;">Channel</span><span style="color:#4f5b66;">)
205    /// </span><span style="color:#4f5b66;">    </span><span style="color:#b48ead;">for</span><span style="color:#4f5b66;"> n=</span><span style="color:#d08770;">1</span><span style="color:#4f5b66;">:</span><span style="color:#d08770;">4
206    /// </span><span style="color:#4f5b66;">        put!(c, 2n)
207    /// </span><span style="color:#4f5b66;">    </span><span style="color:#b48ead;">end
208    /// </span><span style="color:#4f5b66;">    put!(c, &quot;</span><span style="color:#a3be8c;">stop</span><span style="color:#4f5b66;">&quot;)
209    /// </span><span style="color:#b48ead;">end</span><span style="color:#4f5b66;">;
210    /// </span></pre>
211    Base16OceanLight,
212    /// Base16 256
213    ///
214    /// _Doesn't display as HTML well_
215    Base16_256,
216    /// Catppuccin Frappe
217    ///
218    /// <pre style="background-color:#303446;">
219    /// <span style="font-style:italic;color:#949cbb;"># sends a variety of values over a channel
220    /// </span><span style="color:#c6d0f5;">function producer</span><span style="color:#949cbb;">(</span><span style="color:#c6d0f5;">c::</span><span style="font-style:italic;color:#e5c890;">Channel</span><span style="color:#949cbb;">)
221    /// </span><span style="color:#c6d0f5;">    </span><span style="color:#ca9ee6;">for</span><span style="color:#c6d0f5;"> n</span><span style="color:#81c8be;">=</span><span style="color:#ef9f76;">1</span><span style="color:#c6d0f5;">:</span><span style="color:#ef9f76;">4
222    /// </span><span style="color:#c6d0f5;">        put!</span><span style="color:#949cbb;">(</span><span style="color:#c6d0f5;">c</span><span style="color:#949cbb;">,</span><span style="color:#c6d0f5;"> 2n</span><span style="color:#949cbb;">)
223    /// </span><span style="color:#c6d0f5;">    </span><span style="color:#ca9ee6;">end
224    /// </span><span style="color:#c6d0f5;">    put!</span><span style="color:#949cbb;">(</span><span style="color:#c6d0f5;">c</span><span style="color:#949cbb;">, </span><span style="color:#a6d189;">&quot;stop&quot;</span><span style="color:#949cbb;">)
225    /// </span><span style="color:#ca9ee6;">end</span><span style="color:#949cbb;">;
226    /// </span></pre>
227    CatppuccinFrappe,
228    /// Catppuccin Latte
229    ///
230    /// <pre style="background-color:#eff1f5;">
231    /// <span style="font-style:italic;color:#7c7f93;"># sends a variety of values over a channel
232    /// </span><span style="color:#4c4f69;">function producer</span><span style="color:#7c7f93;">(</span><span style="color:#4c4f69;">c::</span><span style="font-style:italic;color:#df8e1d;">Channel</span><span style="color:#7c7f93;">)
233    /// </span><span style="color:#4c4f69;">    </span><span style="color:#8839ef;">for</span><span style="color:#4c4f69;"> n</span><span style="color:#179299;">=</span><span style="color:#fe640b;">1</span><span style="color:#4c4f69;">:</span><span style="color:#fe640b;">4
234    /// </span><span style="color:#4c4f69;">        put!</span><span style="color:#7c7f93;">(</span><span style="color:#4c4f69;">c</span><span style="color:#7c7f93;">,</span><span style="color:#4c4f69;"> 2n</span><span style="color:#7c7f93;">)
235    /// </span><span style="color:#4c4f69;">    </span><span style="color:#8839ef;">end
236    /// </span><span style="color:#4c4f69;">    put!</span><span style="color:#7c7f93;">(</span><span style="color:#4c4f69;">c</span><span style="color:#7c7f93;">, </span><span style="color:#40a02b;">&quot;stop&quot;</span><span style="color:#7c7f93;">)
237    /// </span><span style="color:#8839ef;">end</span><span style="color:#7c7f93;">;
238    /// </span></pre>
239    CatppuccinLatte,
240    /// Catppuccin Macchiato
241    ///
242    /// <pre style="background-color:#24273a;">
243    /// <span style="font-style:italic;color:#939ab7;"># sends a variety of values over a channel
244    /// </span><span style="color:#cad3f5;">function producer</span><span style="color:#939ab7;">(</span><span style="color:#cad3f5;">c::</span><span style="font-style:italic;color:#eed49f;">Channel</span><span style="color:#939ab7;">)
245    /// </span><span style="color:#cad3f5;">    </span><span style="color:#c6a0f6;">for</span><span style="color:#cad3f5;"> n</span><span style="color:#8bd5ca;">=</span><span style="color:#f5a97f;">1</span><span style="color:#cad3f5;">:</span><span style="color:#f5a97f;">4
246    /// </span><span style="color:#cad3f5;">        put!</span><span style="color:#939ab7;">(</span><span style="color:#cad3f5;">c</span><span style="color:#939ab7;">,</span><span style="color:#cad3f5;"> 2n</span><span style="color:#939ab7;">)
247    /// </span><span style="color:#cad3f5;">    </span><span style="color:#c6a0f6;">end
248    /// </span><span style="color:#cad3f5;">    put!</span><span style="color:#939ab7;">(</span><span style="color:#cad3f5;">c</span><span style="color:#939ab7;">, </span><span style="color:#a6da95;">&quot;stop&quot;</span><span style="color:#939ab7;">)
249    /// </span><span style="color:#c6a0f6;">end</span><span style="color:#939ab7;">;
250    /// </span></pre>
251    CatppuccinMacchiato,
252    /// Catppuccin Mocha
253    ///
254    /// <pre style="background-color:#1e1e2e;">
255    /// <span style="font-style:italic;color:#9399b2;"># sends a variety of values over a channel
256    /// </span><span style="color:#cdd6f4;">function producer</span><span style="color:#9399b2;">(</span><span style="color:#cdd6f4;">c::</span><span style="font-style:italic;color:#f9e2af;">Channel</span><span style="color:#9399b2;">)
257    /// </span><span style="color:#cdd6f4;">    </span><span style="color:#cba6f7;">for</span><span style="color:#cdd6f4;"> n</span><span style="color:#94e2d5;">=</span><span style="color:#fab387;">1</span><span style="color:#cdd6f4;">:</span><span style="color:#fab387;">4
258    /// </span><span style="color:#cdd6f4;">        put!</span><span style="color:#9399b2;">(</span><span style="color:#cdd6f4;">c</span><span style="color:#9399b2;">,</span><span style="color:#cdd6f4;"> 2n</span><span style="color:#9399b2;">)
259    /// </span><span style="color:#cdd6f4;">    </span><span style="color:#cba6f7;">end
260    /// </span><span style="color:#cdd6f4;">    put!</span><span style="color:#9399b2;">(</span><span style="color:#cdd6f4;">c</span><span style="color:#9399b2;">, </span><span style="color:#a6e3a1;">&quot;stop&quot;</span><span style="color:#9399b2;">)
261    /// </span><span style="color:#cba6f7;">end</span><span style="color:#9399b2;">;
262    /// </span></pre>
263    CatppuccinMocha,
264    /// Coldark-Cold
265    ///
266    /// <pre style="background-color:#e3eaf2;">
267    /// <span style="color:#3c526d;"># sends a variety of values over a channel
268    /// </span><span style="color:#111b27;">function producer(c::Channel)
269    /// </span><span style="color:#111b27;">    </span><span style="color:#a04900;">for</span><span style="color:#111b27;"> n</span><span style="color:#a04900;">=</span><span style="color:#755f00;">1</span><span style="color:#111b27;">:</span><span style="color:#755f00;">4
270    /// </span><span style="color:#111b27;">        put!(c, 2n)
271    /// </span><span style="color:#111b27;">    </span><span style="color:#a04900;">end
272    /// </span><span style="color:#111b27;">    put!(c, </span><span style="color:#116b00;">&quot;stop&quot;</span><span style="color:#111b27;">)
273    /// </span><span style="color:#a04900;">end</span><span style="color:#111b27;">;
274    /// </span></pre>
275    ColdarkCold,
276    /// Coldark-Dark
277    ///
278    /// <pre style="background-color:#111b27;">
279    /// <span style="color:#8da1b9;"># sends a variety of values over a channel
280    /// </span><span style="color:#e3eaf2;">function producer(c::Channel)
281    /// </span><span style="color:#e3eaf2;">    </span><span style="color:#e9ae7e;">for</span><span style="color:#e3eaf2;"> n</span><span style="color:#e9ae7e;">=</span><span style="color:#e6d37a;">1</span><span style="color:#e3eaf2;">:</span><span style="color:#e6d37a;">4
282    /// </span><span style="color:#e3eaf2;">        put!(c, 2n)
283    /// </span><span style="color:#e3eaf2;">    </span><span style="color:#e9ae7e;">end
284    /// </span><span style="color:#e3eaf2;">    put!(c, </span><span style="color:#91d076;">&quot;stop&quot;</span><span style="color:#e3eaf2;">)
285    /// </span><span style="color:#e9ae7e;">end</span><span style="color:#e3eaf2;">;
286    /// </span></pre>
287    ColdarkDark,
288    /// Dark Neon
289    ///
290    /// <pre style="background-color:#000000;">
291    /// <span style="background-color:#212121;color:#7c7c7c;"># sends a variety of values over a channel
292    /// </span><span style="color:#ffffff;">function producer(c::</span><span style="color:#f8f8f8;">Channel</span><span style="color:#ffffff;">)
293    /// </span><span style="color:#ffffff;">    </span><span style="color:#66ccff;">for</span><span style="color:#ffffff;"> n</span><span style="color:#aaaaaa;">=</span><span style="font-weight:bold;color:#ff73fd;">1</span><span style="color:#ffffff;">:</span><span style="font-weight:bold;color:#ff73fd;">4
294    /// </span><span style="color:#ffffff;">        put!(c, 2n)
295    /// </span><span style="color:#ffffff;">    </span><span style="color:#66ccff;">end
296    /// </span><span style="color:#ffffff;">    put!(c, </span><span style="color:#ccff66;">&quot;stop&quot;</span><span style="color:#ffffff;">)
297    /// </span><span style="color:#66ccff;">end</span><span style="color:#ffffff;">;
298    /// </span></pre>
299    DarkNeon,
300    /// Dracula
301    ///
302    /// <pre style="background-color:#282a36;">
303    /// <span style="color:#6272a4;"># sends a variety of values over a channel
304    /// </span><span style="color:#f8f8f2;">function producer(c::</span><span style="text-decoration:underline;color:#8be9fd;">Channel</span><span style="color:#f8f8f2;">)
305    /// </span><span style="color:#f8f8f2;">    </span><span style="color:#ff79c6;">for</span><span style="color:#f8f8f2;"> n</span><span style="color:#ff79c6;">=</span><span style="color:#bd93f9;">1</span><span style="color:#f8f8f2;">:</span><span style="color:#bd93f9;">4
306    /// </span><span style="color:#f8f8f2;">        put!(c, 2n)
307    /// </span><span style="color:#f8f8f2;">    </span><span style="color:#ff79c6;">end
308    /// </span><span style="color:#f8f8f2;">    put!(c, </span><span style="color:#f1fa8c;">&quot;stop&quot;</span><span style="color:#f8f8f2;">)
309    /// </span><span style="color:#ff79c6;">end</span><span style="color:#f8f8f2;">;
310    /// </span></pre>
311    Dracula,
312    /// GitHub
313    ///
314    /// <pre style="background-color:#ffffff;">
315    /// <span style="color:#969896;"># sends a variety of values over a channel
316    /// </span><span style="color:#333333;">function producer(c::Channel)
317    /// </span><span style="color:#333333;">    </span><span style="color:#a71d5d;">for</span><span style="color:#333333;"> n</span><span style="color:#a71d5d;">=</span><span style="color:#0086b3;">1</span><span style="color:#333333;">:</span><span style="color:#0086b3;">4
318    /// </span><span style="color:#333333;">        put!(c, 2n)
319    /// </span><span style="color:#333333;">    </span><span style="color:#a71d5d;">end
320    /// </span><span style="color:#333333;">    put!(c, </span><span style="color:#183691;">&quot;stop&quot;</span><span style="color:#333333;">)
321    /// </span><span style="color:#a71d5d;">end</span><span style="color:#333333;">;
322    /// </span></pre>
323    Github,
324    /// gruvbox (Dark)
325    ///
326    /// <pre style="background-color:#282828;">
327    /// <span style="font-style:italic;color:#928374;"># sends a variety of values over a channel
328    /// </span><span style="color:#fbf1c7;">function producer(c::</span><span style="color:#fabd2f;">Channel</span><span style="color:#fbf1c7;">)
329    /// </span><span style="color:#fbf1c7;">    </span><span style="color:#fb4934;">for</span><span style="color:#fbf1c7;"> n</span><span style="color:#8ec07c;">=</span><span style="color:#d3869b;">1</span><span style="color:#fbf1c7;">:</span><span style="color:#d3869b;">4
330    /// </span><span style="color:#fbf1c7;">        put!(c, 2n)
331    /// </span><span style="color:#fbf1c7;">    </span><span style="color:#fb4934;">end
332    /// </span><span style="color:#fbf1c7;">    put!(c, &quot;</span><span style="color:#b8bb26;">stop</span><span style="color:#fbf1c7;">&quot;)
333    /// </span><span style="color:#fb4934;">end</span><span style="color:#fbf1c7;">;
334    /// </span></pre>
335    GruvboxDark,
336    /// gruvbox (Light)
337    ///
338    /// <pre style="background-color:#fbf1c7;">
339    /// <span style="font-style:italic;color:#928374;"># sends a variety of values over a channel
340    /// </span><span style="color:#282828;">function producer(c::</span><span style="color:#b57614;">Channel</span><span style="color:#282828;">)
341    /// </span><span style="color:#282828;">    </span><span style="color:#9d0006;">for</span><span style="color:#282828;"> n</span><span style="color:#427b58;">=</span><span style="color:#8f3f71;">1</span><span style="color:#282828;">:</span><span style="color:#8f3f71;">4
342    /// </span><span style="color:#282828;">        put!(c, 2n)
343    /// </span><span style="color:#282828;">    </span><span style="color:#9d0006;">end
344    /// </span><span style="color:#282828;">    put!(c, &quot;</span><span style="color:#79740e;">stop</span><span style="color:#282828;">&quot;)
345    /// </span><span style="color:#9d0006;">end</span><span style="color:#282828;">;
346    /// </span></pre>
347    GruvboxLight,
348    /// Inspired GitHub
349    ///
350    /// <pre style="background-color:#ffffff;">
351    /// <span style="font-style:italic;color:#969896;"># sends a variety of values over a channel
352    /// </span><span style="color:#323232;">function producer(c::</span><span style="color:#0086b3;">Channel</span><span style="color:#323232;">)
353    /// </span><span style="color:#323232;">    </span><span style="font-weight:bold;color:#a71d5d;">for</span><span style="color:#323232;"> n</span><span style="font-weight:bold;color:#a71d5d;">=</span><span style="color:#0086b3;">1</span><span style="color:#323232;">:</span><span style="color:#0086b3;">4
354    /// </span><span style="color:#323232;">        put!(c, 2n)
355    /// </span><span style="color:#323232;">    </span><span style="font-weight:bold;color:#a71d5d;">end
356    /// </span><span style="color:#323232;">    put!(c, </span><span style="color:#183691;">&quot;stop&quot;</span><span style="color:#323232;">)
357    /// </span><span style="font-weight:bold;color:#a71d5d;">end</span><span style="color:#323232;">;
358    /// </span></pre>
359    InspiredGithub,
360    /// 1337
361    ///
362    /// <pre style="background-color:#191919;">
363    /// <span style="color:#6d6d6d;"># sends a variety of values over a channel
364    /// </span><span style="color:#f8f8f2;">function producer(c::</span><span style="text-decoration:underline;color:#8cdaff;">Channel</span><span style="color:#f8f8f2;">)
365    /// </span><span style="color:#f8f8f2;">    </span><span style="color:#ff5e5e;">for</span><span style="color:#f8f8f2;"> n</span><span style="color:#ff5e5e;">=</span><span style="color:#fdb082;">1</span><span style="color:#f8f8f2;">:</span><span style="color:#fdb082;">4
366    /// </span><span style="color:#f8f8f2;">        put!(c, 2n)
367    /// </span><span style="color:#f8f8f2;">    </span><span style="color:#ff5e5e;">end
368    /// </span><span style="color:#f8f8f2;">    put!(c, </span><span style="color:#ffffff;">&quot;</span><span style="color:#fbe3bf;">stop</span><span style="color:#ffffff;">&quot;</span><span style="color:#f8f8f2;">)
369    /// </span><span style="color:#ff5e5e;">end</span><span style="color:#f8f8f2;">;
370    /// </span></pre>
371    Leet,
372    /// Monokai Extended
373    ///
374    /// <pre style="background-color:#222222;">
375    /// <span style="color:#75715e;"># sends a variety of values over a channel
376    /// </span><span style="color:#f8f8f2;">function producer(c::</span><span style="text-decoration:underline;color:#66d9ef;">Channel</span><span style="color:#f8f8f2;">)
377    /// </span><span style="color:#f8f8f2;">    </span><span style="color:#f92672;">for</span><span style="color:#f8f8f2;"> n</span><span style="color:#f92672;">=</span><span style="color:#be84ff;">1</span><span style="color:#f8f8f2;">:</span><span style="color:#be84ff;">4
378    /// </span><span style="color:#f8f8f2;">        put!(c, 2n)
379    /// </span><span style="color:#f8f8f2;">    </span><span style="color:#f92672;">end
380    /// </span><span style="color:#f8f8f2;">    put!(c, </span><span style="color:#e6db74;">&quot;stop&quot;</span><span style="color:#f8f8f2;">)
381    /// </span><span style="color:#f92672;">end</span><span style="color:#f8f8f2;">;
382    /// </span></pre>
383    MonokaiExtended,
384    /// Monokai Extended Bright
385    ///
386    /// <pre style="background-color:#272822;">
387    /// <span style="color:#75715e;"># sends a variety of values over a channel
388    /// </span><span style="color:#f8f8f2;">function producer(c::</span><span style="text-decoration:underline;color:#a6e22e;">Channel</span><span style="color:#f8f8f2;">)
389    /// </span><span style="color:#f8f8f2;">    </span><span style="color:#f92672;">for</span><span style="color:#f8f8f2;"> n</span><span style="color:#f92672;">=</span><span style="color:#ae81ff;">1</span><span style="color:#f8f8f2;">:</span><span style="color:#ae81ff;">4
390    /// </span><span style="color:#f8f8f2;">        put!(c, 2n)
391    /// </span><span style="color:#f8f8f2;">    </span><span style="color:#f92672;">end
392    /// </span><span style="color:#f8f8f2;">    put!(c, </span><span style="color:#e6db74;">&quot;stop&quot;</span><span style="color:#f8f8f2;">)
393    /// </span><span style="color:#f92672;">end</span><span style="color:#f8f8f2;">;
394    /// </span></pre>
395    MonokaiExtendedBright,
396    /// Monokai Extended Light
397    ///
398    /// <pre style="background-color:#fafafa;">
399    /// <span style="color:#75715e;"># sends a variety of values over a channel
400    /// </span><span style="color:#49483e;">function producer(c::</span><span style="text-decoration:underline;color:#679c00;">Channel</span><span style="color:#49483e;">)
401    /// </span><span style="color:#49483e;">    </span><span style="color:#f9005a;">for</span><span style="color:#49483e;"> n</span><span style="color:#f9005a;">=</span><span style="color:#684d99;">1</span><span style="color:#49483e;">:</span><span style="color:#684d99;">4
402    /// </span><span style="color:#49483e;">        put!(c, 2n)
403    /// </span><span style="color:#49483e;">    </span><span style="color:#f9005a;">end
404    /// </span><span style="color:#49483e;">    put!(c, </span><span style="color:#998f2f;">&quot;stop&quot;</span><span style="color:#49483e;">)
405    /// </span><span style="color:#f9005a;">end</span><span style="color:#49483e;">;
406    /// </span></pre>
407    MonokaiExtendedLight,
408    /// Monokai Extended Origin
409    ///
410    /// <pre style="background-color:#272822;">
411    /// <span style="color:#75715e;"># sends a variety of values over a channel
412    /// </span><span style="color:#f8f8f2;">function producer(c::</span><span style="text-decoration:underline;color:#a6e22e;">Channel</span><span style="color:#f8f8f2;">)
413    /// </span><span style="color:#f8f8f2;">    </span><span style="color:#f92672;">for</span><span style="color:#f8f8f2;"> n</span><span style="color:#f92672;">=</span><span style="color:#ae81ff;">1</span><span style="color:#f8f8f2;">:</span><span style="color:#ae81ff;">4
414    /// </span><span style="color:#f8f8f2;">        put!(c, 2n)
415    /// </span><span style="color:#f8f8f2;">    </span><span style="color:#f92672;">end
416    /// </span><span style="color:#f8f8f2;">    put!(c, </span><span style="color:#e6db74;">&quot;stop&quot;</span><span style="color:#f8f8f2;">)
417    /// </span><span style="color:#f92672;">end</span><span style="color:#f8f8f2;">;
418    /// </span></pre>
419    MonokaiExtendedOrigin,
420    /// Nord
421    ///
422    /// <pre style="background-color:#2e3440;">
423    /// <span style="color:#616e88;"># sends a variety of values over a channel
424    /// </span><span style="color:#d8dee9;">function producer(c::</span><span style="color:#8fbcbb;">Channel</span><span style="color:#d8dee9;">)
425    /// </span><span style="color:#d8dee9;">    </span><span style="color:#81a1c1;">for</span><span style="color:#d8dee9;"> n</span><span style="color:#81a1c1;">=</span><span style="color:#b48ead;">1</span><span style="color:#d8dee9;">:</span><span style="color:#b48ead;">4
426    /// </span><span style="color:#d8dee9;">        put!(c</span><span style="color:#eceff4;">,</span><span style="color:#d8dee9;"> 2n)
427    /// </span><span style="color:#d8dee9;">    </span><span style="color:#81a1c1;">end
428    /// </span><span style="color:#d8dee9;">    put!(c</span><span style="color:#eceff4;">, </span><span style="color:#a3be8c;">&quot;stop&quot;</span><span style="color:#d8dee9;">)
429    /// </span><span style="color:#81a1c1;">end</span><span style="color:#eceff4;">;
430    /// </span></pre>
431    Nord,
432    /// One Half Dark
433    ///
434    /// <pre style="background-color:#282c34;">
435    /// <span style="color:#5c6370;"># sends a variety of values over a channel
436    /// </span><span style="color:#dcdfe4;">function producer(c::</span><span style="color:#e5c07b;">Channel</span><span style="color:#dcdfe4;">)
437    /// </span><span style="color:#dcdfe4;">    </span><span style="color:#c678dd;">for</span><span style="color:#dcdfe4;"> n</span><span style="color:#c678dd;">=</span><span style="color:#e5c07b;">1</span><span style="color:#dcdfe4;">:</span><span style="color:#e5c07b;">4
438    /// </span><span style="color:#dcdfe4;">        put!(c, 2n)
439    /// </span><span style="color:#dcdfe4;">    </span><span style="color:#c678dd;">end
440    /// </span><span style="color:#dcdfe4;">    put!(c, </span><span style="color:#98c379;">&quot;stop&quot;</span><span style="color:#dcdfe4;">)
441    /// </span><span style="color:#c678dd;">end</span><span style="color:#dcdfe4;">;
442    /// </span></pre>
443    OneHalfDark,
444    /// One Half Light
445    ///
446    /// <pre style="background-color:#fafafa;">
447    /// <span style="color:#a0a1a7;"># sends a variety of values over a channel
448    /// </span><span style="color:#383a42;">function producer(c::</span><span style="color:#c18401;">Channel</span><span style="color:#383a42;">)
449    /// </span><span style="color:#383a42;">    </span><span style="color:#a626a4;">for</span><span style="color:#383a42;"> n</span><span style="color:#a626a4;">=</span><span style="color:#c18401;">1</span><span style="color:#383a42;">:</span><span style="color:#c18401;">4
450    /// </span><span style="color:#383a42;">        put!(c, 2n)
451    /// </span><span style="color:#383a42;">    </span><span style="color:#a626a4;">end
452    /// </span><span style="color:#383a42;">    put!(c, </span><span style="color:#50a14f;">&quot;stop&quot;</span><span style="color:#383a42;">)
453    /// </span><span style="color:#a626a4;">end</span><span style="color:#383a42;">;
454    /// </span></pre>
455    OneHalfLight,
456    /// Solarized (dark)
457    ///
458    /// <pre style="background-color:#002b36;">
459    /// <span style="color:#586e75;"># sends a variety of values over a channel
460    /// </span><span style="color:#839496;">function producer</span><span style="color:#657b83;">(</span><span style="color:#839496;">c::</span><span style="color:#b58900;">Channel</span><span style="color:#657b83;">)
461    /// </span><span style="color:#839496;">    </span><span style="color:#859900;">for</span><span style="color:#839496;"> n</span><span style="color:#657b83;">=</span><span style="color:#6c71c4;">1</span><span style="color:#839496;">:</span><span style="color:#6c71c4;">4
462    /// </span><span style="color:#839496;">        put!</span><span style="color:#657b83;">(</span><span style="color:#839496;">c, 2n</span><span style="color:#657b83;">)
463    /// </span><span style="color:#839496;">    </span><span style="color:#859900;">end
464    /// </span><span style="color:#839496;">    put!</span><span style="color:#657b83;">(</span><span style="color:#839496;">c, &quot;</span><span style="color:#2aa198;">stop</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)
465    /// </span><span style="color:#859900;">end</span><span style="color:#839496;">;
466    /// </span></pre>
467    SolarizedDark,
468    /// Solarized (light)
469    ///
470    /// <pre style="background-color:#fdf6e3;">
471    /// <span style="color:#93a1a1;"># sends a variety of values over a channel
472    /// </span><span style="color:#657b83;">function producer(c::</span><span style="color:#b58900;">Channel</span><span style="color:#657b83;">)
473    /// </span><span style="color:#657b83;">    </span><span style="color:#859900;">for</span><span style="color:#657b83;"> n=</span><span style="color:#6c71c4;">1</span><span style="color:#657b83;">:</span><span style="color:#6c71c4;">4
474    /// </span><span style="color:#657b83;">        put!(c, 2n)
475    /// </span><span style="color:#657b83;">    </span><span style="color:#859900;">end
476    /// </span><span style="color:#657b83;">    put!(c, </span><span style="color:#839496;">&quot;</span><span style="color:#2aa198;">stop</span><span style="color:#839496;">&quot;</span><span style="color:#657b83;">)
477    /// </span><span style="color:#859900;">end</span><span style="color:#657b83;">;
478    /// </span></pre>
479    SolarizedLight,
480    /// Sublime Snazzy
481    ///
482    /// <pre style="background-color:#282a36;">
483    /// <span style="color:#686868;"># sends a variety of values over a channel
484    /// </span><span style="color:#f8f8f2;">function producer(c::</span><span style="text-decoration:underline;color:#9aedfe;">Channel</span><span style="color:#f8f8f2;">)
485    /// </span><span style="color:#f8f8f2;">    </span><span style="color:#ff5c57;">for</span><span style="color:#f8f8f2;"> n</span><span style="color:#ff5c57;">=</span><span style="color:#f1f1f0;">1</span><span style="color:#f8f8f2;">:</span><span style="color:#f1f1f0;">4
486    /// </span><span style="color:#f8f8f2;">        put!(c, 2n)
487    /// </span><span style="color:#f8f8f2;">    </span><span style="color:#ff5c57;">end
488    /// </span><span style="color:#f8f8f2;">    put!(c, </span><span style="color:#f3f99d;">&quot;stop&quot;</span><span style="color:#f8f8f2;">)
489    /// </span><span style="color:#ff5c57;">end</span><span style="color:#f8f8f2;">;
490    /// </span></pre>
491    SublimeSnazzy,
492    /// TwoDark
493    ///
494    /// <pre style="background-color:#282c34;">
495    /// <span style="font-style:italic;color:#5c6370;"># sends a variety of values over a channel
496    /// </span><span style="color:#abb2bf;">function producer(c::</span><span style="color:#e5c07b;">Channel</span><span style="color:#abb2bf;">)
497    /// </span><span style="color:#abb2bf;">    </span><span style="color:#c678dd;">for</span><span style="color:#abb2bf;"> n=</span><span style="color:#d19a66;">1</span><span style="color:#abb2bf;">:</span><span style="color:#d19a66;">4
498    /// </span><span style="color:#abb2bf;">        put!(c, 2n)
499    /// </span><span style="color:#abb2bf;">    </span><span style="color:#c678dd;">end
500    /// </span><span style="color:#abb2bf;">    put!(c, </span><span style="color:#98c379;">&quot;stop&quot;</span><span style="color:#abb2bf;">)
501    /// </span><span style="color:#c678dd;">end</span><span style="color:#abb2bf;">;
502    /// </span></pre>
503    TwoDark,
504    /// zenburn
505    ///
506    /// <pre style="background-color:#3f3f3f;">
507    /// <span style="color:#a0cfa1;">#</span><span style="color:#87ae86;"> sends a variety of values over a channel
508    /// </span><span style="color:#dedede;">function producer(c::Channel)
509    /// </span><span style="color:#dedede;">    </span><span style="color:#fed6af;">for</span><span style="color:#dedede;"> n</span><span style="color:#ececec;">=</span><span style="color:#87d6d5;">1</span><span style="color:#dedede;">:</span><span style="color:#87d6d5;">4
510    /// </span><span style="color:#dedede;">        put!(c, 2n)
511    /// </span><span style="color:#dedede;">    </span><span style="color:#fed6af;">end
512    /// </span><span style="color:#dedede;">    put!(c, </span><span style="color:#d6d6d680;">&quot;</span><span style="color:#d68686;">stop</span><span style="color:#d6d6d680;">&quot;</span><span style="color:#dedede;">)
513    /// </span><span style="color:#fed6af;">end</span><span style="color:#dedede;">;
514    /// </span></pre>
515    Zenburn,
516}
517
518impl EmbeddedThemeName {
519    /// The name of each embedded theme
520    ///
521    /// This matches the key used for each theme in [`ThemeSet`]'s `themes`
522    ///
523    /// ```
524    /// use two_face::theme::EmbeddedThemeName;
525    ///
526    /// assert_eq!(
527    ///     EmbeddedThemeName::Leet.as_name(),
528    ///     "1337",
529    /// );
530    /// // `.as_name()` is used for `Display` too!
531    /// assert_eq!(
532    ///     EmbeddedThemeName::SolarizedDark.to_string(),
533    ///     "Solarized (dark)",
534    /// );
535    /// ```
536    pub fn as_name(self) -> &'static str {
537        match self {
538            Self::Ansi => "ansi",
539            Self::Base16 => "base16",
540            Self::Base16EightiesDark => "base16-eighties.dark",
541            Self::Base16MochaDark => "base16-mocha.dark",
542            Self::Base16OceanDark => "base16-ocean.dark",
543            Self::Base16OceanLight => "base16-ocean.light",
544            Self::Base16_256 => "base16-256",
545            Self::CatppuccinFrappe => "Catppuccin Frappe",
546            Self::CatppuccinLatte => "Catppuccin Latte",
547            Self::CatppuccinMacchiato => "Catppuccin Macchiato",
548            Self::CatppuccinMocha => "Catppuccin Mocha",
549            Self::ColdarkCold => "Coldark-Cold",
550            Self::ColdarkDark => "Coldark-Dark",
551            Self::DarkNeon => "DarkNeon",
552            Self::Dracula => "Dracula",
553            Self::Github => "GitHub",
554            Self::GruvboxDark => "gruvbox-dark",
555            Self::GruvboxLight => "gruvbox-light",
556            Self::InspiredGithub => "InspiredGitHub",
557            Self::Leet => "1337",
558            Self::MonokaiExtended => "Monokai Extended",
559            Self::MonokaiExtendedBright => "Monokai Extended Bright",
560            Self::MonokaiExtendedLight => "Monokai Extended Light",
561            Self::MonokaiExtendedOrigin => "Monokai Extended Origin",
562            Self::Nord => "Nord",
563            Self::OneHalfDark => "OneHalfDark",
564            Self::OneHalfLight => "OneHalfLight",
565            Self::SolarizedDark => "Solarized (dark)",
566            Self::SolarizedLight => "Solarized (light)",
567            Self::SublimeSnazzy => "Sublime Snazzy",
568            Self::TwoDark => "TwoDark",
569            Self::Zenburn => "zenburn",
570        }
571    }
572}
573
574impl fmt::Display for EmbeddedThemeName {
575    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
576        f.write_str(self.as_name())
577    }
578}
579
580#[cfg(test)]
581mod tests {
582    use std::collections::BTreeSet;
583
584    use super::*;
585
586    use strum::IntoEnumIterator;
587
588    #[test]
589    fn theme_set_roundtrip() {
590        let theme_set: ThemeSet = extra().into();
591        let lazy: LazyThemeSet = (&theme_set).into();
592        let theme_set_again: ThemeSet = lazy.into();
593        let eq = theme_set
594            .themes
595            .into_iter()
596            .zip(theme_set_again.themes.into_iter())
597            .all(|(pair1, pair2)| pair1 == pair2);
598        assert!(eq);
599    }
600
601    #[test]
602    fn embedded_theme_is_exhaustive() {
603        let theme_set = extra();
604        for theme_name in EmbeddedThemeName::iter() {
605            println!("Getting: {:?}", theme_name);
606            let _ = theme_set.get(theme_name);
607        }
608
609        assert_eq!(theme_set.0.themes.len(), EmbeddedThemeName::iter().len());
610        assert_eq!(
611            EmbeddedLazyThemeSet::theme_names().len(),
612            EmbeddedThemeName::iter().len()
613        );
614
615        let all_unique: BTreeSet<_> = EmbeddedLazyThemeSet::theme_names().iter().collect();
616        assert_eq!(all_unique.len(), EmbeddedLazyThemeSet::theme_names().len());
617    }
618}