use std::{collections::HashMap, path::Path};
use crate::{
ThemeError,
captures::CaptureMap,
color::{Color, RawPalette},
palette::Palette,
style::{RawStyleSpec, RawUiStyles, StyleSpec, UiStyles},
};
#[derive(Clone, Default, Debug)]
pub struct Theme {
pub palette: HashMap<String, Color>,
pub ui: UiStyles,
pub captures: CaptureMap,
}
impl Theme {
pub fn from_toml_str(s: &str) -> Result<Self, ThemeError> {
let mut table: toml::Table = toml::from_str(s)?;
let palette = if let Some(v) = table.remove("palette") {
let raw: RawPalette = v.try_into()?;
Palette::from_raw(raw)
} else {
Palette::default()
};
let raw_ui: Option<RawUiStyles> = if let Some(v) = table.remove("ui") {
Some(v.try_into()?)
} else {
None
};
let ui = raw_ui
.map(|raw| raw.resolve(&palette.0))
.transpose()?
.unwrap_or_default();
let mut flat: HashMap<String, StyleSpec> = HashMap::new();
for (key, val) in table {
let raw: RawStyleSpec = val.try_into()?;
flat.insert(key, raw.resolve(&palette.0)?);
}
Ok(Theme {
palette: palette.0,
ui,
captures: CaptureMap::from_map(flat),
})
}
pub fn from_path(p: &Path) -> Result<Self, ThemeError> {
let s = std::fs::read_to_string(p)?;
Self::from_toml_str(&s)
}
}