Parse hex colour codes in serde:🇩🇪:Deserialize (#801)

This commit is contained in:
Peter Hebden 2023-08-05 14:25:59 +01:00 committed by GitHub
parent 2cb2658180
commit ff01914328
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -271,7 +271,7 @@ impl<'de> serde::de::Deserialize<'de> for Color {
type Value = Color;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(
"`black`, `blue`, `dark_blue`, `cyan`, `dark_cyan`, `green`, `dark_green`, `grey`, `dark_grey`, `magenta`, `dark_magenta`, `red`, `dark_red`, `white`, `yellow`, `dark_yellow`, `ansi_(value)`, or `rgb_(r,g,b)`",
"`black`, `blue`, `dark_blue`, `cyan`, `dark_cyan`, `green`, `dark_green`, `grey`, `dark_grey`, `magenta`, `dark_magenta`, `red`, `dark_red`, `white`, `yellow`, `dark_yellow`, `ansi_(value)`, or `rgb_(r,g,b)` or `#rgbhex`",
)
}
fn visit_str<E>(self, value: &str) -> Result<Color, E>
@ -304,6 +304,20 @@ impl<'de> serde::de::Deserialize<'de> for Color {
let g = results[1].parse::<u8>();
let b = results[2].parse::<u8>();
if r.is_ok() && g.is_ok() && b.is_ok() {
return Ok(Color::Rgb {
r: r.unwrap(),
g: g.unwrap(),
b: b.unwrap(),
});
}
}
} else if let Some(hex) = value.strip_prefix('#') {
if hex.is_ascii() && hex.len() == 6 {
let r = u8::from_str_radix(&hex[0..2], 16);
let g = u8::from_str_radix(&hex[2..4], 16);
let b = u8::from_str_radix(&hex[4..6], 16);
if r.is_ok() && g.is_ok() && b.is_ok() {
return Ok(Color::Rgb {
r: r.unwrap(),
@ -476,4 +490,24 @@ mod serde_tests {
assert!(serde_json::from_str::<Color>("\"rgb_(255,255,255,255)\"").is_err());
assert!(serde_json::from_str::<Color>("\"rgb_(256,255,255)\"").is_err());
}
#[test]
fn test_deserial_rgb_hex() {
assert_eq!(
serde_json::from_str::<Color>("\"#ffffff\"").unwrap(),
Color::from((255, 255, 255))
);
assert_eq!(
serde_json::from_str::<Color>("\"#FFFFFF\"").unwrap(),
Color::from((255, 255, 255))
);
}
#[test]
fn test_deserial_unvalid_rgb_hex() {
assert!(serde_json::from_str::<Color>("\"#FFFFFFFF\"").is_err());
assert!(serde_json::from_str::<Color>("\"#FFGFFF\"").is_err());
// Ferris is 4 bytes so this will be considered the correct length.
assert!(serde_json::from_str::<Color>("\"#ff🦀\"").is_err());
}
}