diff options
author | Ramon <rg2872078+gh2@gmail.com> | 2022-06-23 23:05:34 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-24 12:05:34 +0900 |
commit | b3fab84557347eeed0fe06656e20cad88b0062b8 (patch) | |
tree | fba6f8bb103127463f0c62180c5297aa49d06a23 /zellij-utils/src/input/theme.rs | |
parent | 59d753dc2f48e591aedb59e0b3e4710516c7be42 (diff) |
feat(theme): allow hex colors for themes (#1536)
* feat(theme): allow hex colors for themes
* feat(theme): allow hex strings to start with #
* fix: fix formatting issue
* fix: remove debug print statement
* fix: apply clippy suggestion for # code
Co-authored-by: ramonGonzEdu <rg2872079@gmail.com>
Diffstat (limited to 'zellij-utils/src/input/theme.rs')
-rw-r--r-- | zellij-utils/src/input/theme.rs | 73 |
1 files changed, 71 insertions, 2 deletions
diff --git a/zellij-utils/src/input/theme.rs b/zellij-utils/src/input/theme.rs index 08b74bc36..6a1bc7639 100644 --- a/zellij-utils/src/input/theme.rs +++ b/zellij-utils/src/input/theme.rs @@ -1,5 +1,8 @@ -use serde::{Deserialize, Serialize}; -use std::collections::HashMap; +use serde::{ + de::{Error, Visitor}, + Deserialize, Deserializer, Serialize, Serializer, +}; +use std::{collections::HashMap, fmt}; use super::options::Options; use crate::shared::detect_theme_hue; @@ -48,6 +51,71 @@ pub struct PaletteFromYaml { pub enum PaletteColorFromYaml { Rgb((u8, u8, u8)), EightBit(u8), + Hex(HexColor), +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +pub struct HexColor(u8, u8, u8); + +impl From<HexColor> for (u8, u8, u8) { + fn from(e: HexColor) -> (u8, u8, u8) { + let HexColor(r, g, b) = e; + (r, g, b) + } +} + +pub struct HexColorVisitor(); + +impl<'de> Visitor<'de> for HexColorVisitor { + type Value = HexColor; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + write!(formatter, "a hex color in the format #RGB or #RRGGBB") + } + + fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> + where + E: Error, + { + if let Some(stripped) = s.strip_prefix('#') { + return self.visit_str(stripped); + } + + if s.len() == 3 { + Ok(HexColor( + u8::from_str_radix(&s[0..1], 16).map_err(E::custom)? * 0x11, + u8::from_str_radix(&s[1..2], 16).map_err(E::custom)? * 0x11, + u8::from_str_radix(&s[2..3], 16).map_err(E::custom)? * 0x11, + )) + } else if s.len() == 6 { + Ok(HexColor( + u8::from_str_radix(&s[0..2], 16).map_err(E::custom)?, + u8::from_str_radix(&s[2..4], 16).map_err(E::custom)?, + u8::from_str_radix(&s[4..6], 16).map_err(E::custom)?, + )) + } else { + Err(Error::custom( + "Hex color must be of form \"#RGB\" or \"#RRGGBB\"", + )) + } + } +} + +impl<'de> Deserialize<'de> for HexColor { + fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> + where + D: Deserializer<'de>, + { + deserializer.deserialize_str(HexColorVisitor()) + } +} +impl Serialize for HexColor { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + serializer.serialize_str(format!("{:02X}{:02X}{:02X}", self.0, self.1, self.2).as_str()) + } } impl Default for PaletteColorFromYaml { @@ -109,6 +177,7 @@ impl From<PaletteColorFromYaml> for PaletteColor { match yaml { PaletteColorFromYaml::Rgb(color) => PaletteColor::Rgb(color), PaletteColorFromYaml::EightBit(color) => PaletteColor::EightBit(color), + PaletteColorFromYaml::Hex(color) => PaletteColor::Rgb(color.into()), } } } |