use std::ops::Deref; use termion::color; #[derive(Clone, Copy, Debug)] pub struct Theme { pub colors: Colors, } #[derive(Clone, Copy, Debug)] pub struct ColorSet { pub fg: Color, pub bg: Color, } impl Default for ColorSet { fn default() -> Self { Self { fg: "#ffffff".into(), bg: "#000000".into(), } } } impl ToString for ColorSet { #[inline(always)] fn to_string(&self) -> String { self.bg.bg_string() + &self.fg.fg_string() } } #[derive(Clone, Copy, Debug)] pub struct Colors { pub primary: ColorSet, pub frame: ColorSet, pub subwin: ColorSet, } impl Theme {} #[derive(Clone, Copy, Debug)] pub struct Color(color::Rgb); impl Deref for Color { type Target = color::Rgb; fn deref(&self) -> &Self::Target { &self.0 } } impl TryFrom for Color { type Error = anyhow::Error; fn try_from(value: String) -> Result { Ok(value.as_str().try_into()?) } } impl From<&str> for Color { fn from(value: &str) -> Self { if value.len() < 6 || value.len() > 7 { panic!("hex code length invalid: {}", value.len()); } let mut i = 0; if value.starts_with('#') { i = 1; } Self(color::Rgb( u8::from_str_radix(&value[i..i + 2], 16) .expect("red hex"), u8::from_str_radix(&value[i + 2..i + 4], 16) .expect("green hex"), u8::from_str_radix(&value[i + 4..i + 6], 16) .expect("blue hex"), )) } } impl Default for Theme { fn default() -> Self { Self { colors: Colors { primary: ColorSet { fg: "#ffe6ff".into(), bg: "#3b224c".into(), }, frame: ColorSet { fg: "#ffe6ff".into(), bg: "#330033".into(), }, subwin: ColorSet{ fg: "#ffe6ff".into(), bg: "#110011".into() }, }, } } } impl Theme { #[inline(always)] pub fn primary(&self) -> String { self.colors.primary.to_string() } #[inline(always)] pub fn frame(&self) -> String { self.colors.frame.to_string() } }