summaryrefslogtreecommitdiffstats
path: root/zellij-utils/src/input/theme.rs
diff options
context:
space:
mode:
authorRamon <rg2872078+gh2@gmail.com>2022-06-23 23:05:34 -0400
committerGitHub <noreply@github.com>2022-06-24 12:05:34 +0900
commitb3fab84557347eeed0fe06656e20cad88b0062b8 (patch)
treefba6f8bb103127463f0c62180c5297aa49d06a23 /zellij-utils/src/input/theme.rs
parent59d753dc2f48e591aedb59e0b3e4710516c7be42 (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.rs73
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()),
}
}
}