1use std::{collections::HashMap, path::Path};
2
3use crate::{
4 ThemeError,
5 captures::CaptureMap,
6 color::{Color, RawPalette},
7 palette::Palette,
8 style::{RawStyleSpec, RawUiStyles, StyleSpec, UiStyles},
9};
10
11#[derive(Clone, Default, Debug)]
13pub struct Theme {
14 pub palette: HashMap<String, Color>,
16 pub ui: UiStyles,
18 pub captures: CaptureMap,
20}
21
22impl Theme {
23 pub fn from_toml_str(s: &str) -> Result<Self, ThemeError> {
25 let mut table: toml::Table = toml::from_str(s)?;
28
29 let palette = if let Some(v) = table.remove("palette") {
31 let raw: RawPalette = v.try_into()?;
32 Palette::from_raw(raw)
33 } else {
34 Palette::default()
35 };
36
37 let raw_ui: Option<RawUiStyles> = if let Some(v) = table.remove("ui") {
39 Some(v.try_into()?)
40 } else {
41 None
42 };
43 let ui = raw_ui
44 .map(|raw| raw.resolve(&palette.0))
45 .transpose()?
46 .unwrap_or_default();
47
48 let mut flat: HashMap<String, StyleSpec> = HashMap::new();
50 for (key, val) in table {
51 let raw: RawStyleSpec = val.try_into()?;
52 flat.insert(key, raw.resolve(&palette.0)?);
53 }
54
55 Ok(Theme {
56 palette: palette.0,
57 ui,
58 captures: CaptureMap::from_map(flat),
59 })
60 }
61
62 pub fn from_path(p: &Path) -> Result<Self, ThemeError> {
64 let s = std::fs::read_to_string(p)?;
65 Self::from_toml_str(&s)
66 }
67}