textiler_core/theme/
palette.rs1use indexmap::IndexMap;
4use std::borrow::Borrow;
5use std::hash::Hash;
6
7use crate::theme::theme_mode::ThemeMode;
8use crate::theme::Color;
9
10#[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 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}