diff --git a/src/conf/themes.rs b/src/conf/themes.rs index a7db9d8ba..ecd6eff7f 100644 --- a/src/conf/themes.rs +++ b/src/conf/themes.rs @@ -318,16 +318,97 @@ impl<'de> Deserialize<'de> for ThemeValue { } } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone)] pub struct Theme { - #[serde(default)] pub light: HashMap, ThemeAttributeInner>, - #[serde(default)] pub dark: HashMap, ThemeAttributeInner>, - #[serde(flatten, default)] pub other_themes: HashMap, ThemeAttributeInner>>, } +impl<'de> Deserialize<'de> for Theme { + fn deserialize(deserializer: D) -> std::result::Result + where + D: Deserializer<'de>, + { + #[derive(Deserialize)] + struct ThemeOptions { + #[serde(default)] + light: HashMap, ThemeAttributeInnerOptions>, + #[serde(default)] + dark: HashMap, ThemeAttributeInnerOptions>, + #[serde(flatten, default)] + other_themes: HashMap, ThemeAttributeInnerOptions>>, + } + #[derive(Deserialize)] + struct ThemeAttributeInnerOptions { + #[serde(default)] + fg: Option>, + #[serde(default)] + bg: Option>, + #[serde(default)] + attrs: Option>, + } + + let mut ret = Theme::default(); + let mut s = ::deserialize(deserializer)?; + for tk in s.other_themes.keys() { + ret.other_themes.insert(tk.clone(), ret.dark.clone()); + } + + for (k, v) in ret.light.iter_mut() { + if let Some(att) = s.light.get_mut(k).and_then(|att| att.fg.take()) { + v.fg = att; + } + if let Some(att) = s.light.get_mut(k).and_then(|att| att.bg.take()) { + v.bg = att; + } + if let Some(att) = s.light.get_mut(k).and_then(|att| att.attrs.take()) { + v.attrs = att; + } + } + for (k, v) in ret.dark.iter_mut() { + if let Some(att) = s.dark.get_mut(k).and_then(|att| att.fg.take()) { + v.fg = att; + } + if let Some(att) = s.dark.get_mut(k).and_then(|att| att.bg.take()) { + v.bg = att; + } + if let Some(att) = s.dark.get_mut(k).and_then(|att| att.attrs.take()) { + v.attrs = att; + } + } + for (tk, t) in ret.other_themes.iter_mut() { + for (k, v) in t.iter_mut() { + if let Some(att) = s + .other_themes + .get_mut(tk) + .and_then(|theme| theme.get_mut(k)) + .and_then(|att| att.fg.take()) + { + v.fg = att; + } + if let Some(att) = s + .other_themes + .get_mut(tk) + .and_then(|theme| theme.get_mut(k)) + .and_then(|att| att.bg.take()) + { + v.bg = att; + } + if let Some(att) = s + .other_themes + .get_mut(tk) + .and_then(|theme| theme.get_mut(k)) + .and_then(|att| att.attrs.take()) + { + v.attrs = att; + } + } + } + Ok(ret) + } +} + impl Theme { fn validate_keys( name: &str,