textiler_core/theme/
palette.rs

1//! Contains palette
2
3use indexmap::IndexMap;
4use std::borrow::Borrow;
5use std::hash::Hash;
6
7use crate::theme::theme_mode::ThemeMode;
8use crate::theme::Color;
9
10/// A palette contains an assortment of colors
11#[derive(Debug, Clone, PartialEq, Default)]
12pub struct Palette {
13    selector_to_colors: IndexMap<String, ColorByMode>,
14}
15
16impl Palette {
17    pub fn new() -> Self {
18        Self::default()
19    }
20
21    pub fn insert_constant(&mut self, key: &str, val: Color) {
22        let _ = self
23            .selector_to_colors
24            .insert(key.to_string(), ColorByMode::Constant(val));
25    }
26
27    pub fn insert_by_mode(&mut self, key: &str, dark: Color, light: Color) {
28        let _ = self
29            .selector_to_colors
30            .insert(key.to_string(), ColorByMode::ModeBased { dark, light });
31    }
32
33    /// Gets all the selectors for this palette
34    pub fn selectors(&self) -> impl Iterator<Item = &str> {
35        self.selector_to_colors.keys().map(|s| &**s)
36    }
37
38    pub fn select<Q: Eq + Hash + ?Sized>(&self, selector: &Q, mode: &ThemeMode) -> Option<&Color>
39    where
40        String: Borrow<Q>,
41    {
42        let by_mode = self.selector_to_colors.get(selector)?;
43        match by_mode {
44            ColorByMode::Constant(c) => Some(c),
45            ColorByMode::ModeBased { dark, light } => match mode.clone().detect() {
46                ThemeMode::Dark => Some(dark),
47                ThemeMode::Light => Some(light),
48                ThemeMode::System => {
49                    unreachable!()
50                }
51            },
52        }
53    }
54}
55
56#[derive(Debug, Clone, PartialEq)]
57enum ColorByMode {
58    Constant(Color),
59    ModeBased { dark: Color, light: Color },
60}