From 5cac8d4475d8516690cc8b7fb5ac258d86c065ef Mon Sep 17 00:00:00 2001 From: Rafael Beckel Date: Fri, 25 Aug 2023 05:03:24 +0200 Subject: [PATCH] returns hex conversion error variants explicitly --- palette/src/rgb/rgb.rs | 51 +++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/palette/src/rgb/rgb.rs b/palette/src/rgb/rgb.rs index 36d6d1528..56853bdfb 100644 --- a/palette/src/rgb/rgb.rs +++ b/palette/src/rgb/rgb.rs @@ -936,7 +936,7 @@ pub enum FromHexError { ParseIntError(ParseIntError), /// The hex value was not in a valid 3 or 6 character format. HexFormatError(&'static str), - /// The hex value was not in a valid 8 character format. + /// The hex value was not in a valid 4 or 8 character format. RgbaHexFormatError(&'static str), } @@ -946,15 +946,6 @@ impl From for FromHexError { } } -impl From<&'static str> for FromHexError { - fn from(err: &'static str) -> FromHexError { - match err { - err if err.contains("rgba") => FromHexError::RgbaHexFormatError(err), - _ => FromHexError::HexFormatError(err), - } - } -} - impl core::fmt::Display for FromHexError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match &*self { @@ -964,9 +955,11 @@ impl core::fmt::Display for FromHexError { "{}, please use format '#fff', 'fff', '#ffffff' or 'ffffff'.", s ), - FromHexError::RgbaHexFormatError(s) => { - write!(f, "{}, please use format '#ffffffff' or 'ffffffff'.", s) - } + FromHexError::RgbaHexFormatError(s) => write!( + f, + "{}, please use format '#ffff', 'ffff', '#ffffffff' or 'ffffffff'.", + s + ), } } } @@ -1004,7 +997,7 @@ impl FromStr for Rgb { let col: Rgb = Rgb::new(red, green, blue); Ok(col) } - _ => Err("invalid hex code format".into()), + _ => Err(FromHexError::HexFormatError("invalid hex code format")), } } } @@ -1012,11 +1005,19 @@ impl FromStr for Rgb { impl FromStr for Rgba { type Err = FromHexError; - /// Parses a color hex code of format '#ff00bbff' (with or without the leading '#') into a + /// Parses a color hex code of format '#ff00bbff' or '#abcd' (with or without the leading '#') into a /// [`Rgba`] instance. fn from_str(hex: &str) -> Result { let hex_code = hex.strip_prefix('#').map_or(hex, |stripped| stripped); match hex_code.len() { + 4 => { + let red = u8::from_str_radix(&hex_code[..1], 16)?; + let green = u8::from_str_radix(&hex_code[1..2], 16)?; + let blue = u8::from_str_radix(&hex_code[2..3], 16)?; + let alpha = u8::from_str_radix(&hex_code[3..4], 16)?; + let col: Rgba = Rgba::new(red * 17, green * 17, blue * 17, alpha * 17); + Ok(col) + } 8 => { let red = u8::from_str_radix(&hex_code[..2], 16)?; let green = u8::from_str_radix(&hex_code[2..4], 16)?; @@ -1025,7 +1026,7 @@ impl FromStr for Rgba { let col: Rgba = Rgba::new(red, green, blue, alpha); Ok(col) } - _ => Err("invalid rgba hex code format".into()), + _ => Err(FromHexError::RgbaHexFormatError("invalid hex code format")), } } } @@ -1423,8 +1424,18 @@ mod test { assert_eq!(c.unwrap(), Rgb::::new(240, 52, 230)); let c = Rgb::::from_str("abc"); assert_eq!(c.unwrap(), Rgb::::new(170, 187, 204)); + let c = Rgba::::from_str("#08ff"); + assert_eq!(c.unwrap(), Rgba::::new(0, 136, 255, 255)); + let c = Rgba::::from_str("08f0"); + assert_eq!(c.unwrap(), Rgba::::new(0, 136, 255, 0)); + let c = Rgba::::from_str("#da0bce80"); + assert_eq!(c.unwrap(), Rgba::::new(218, 11, 206, 128)); + let c = Rgba::::from_str("f034e680"); + assert_eq!(c.unwrap(), Rgba::::new(240, 52, 230, 128)); let c = Rgba::::from_str("#ffffffff"); assert_eq!(c.unwrap(), Rgba::::new(255, 255, 255, 255)); + let c = Rgba::::from_str("#ffff"); + assert_eq!(c.unwrap(), Rgba::::new(255, 255, 255, 255)); let c = Rgba::::from_str("#gggggggg"); assert!(c.is_err()); assert_eq!( @@ -1434,14 +1445,14 @@ mod test { let c = Rgba::::from_str("#fff"); assert_eq!( format!("{}", c.err().unwrap()), - "invalid rgba hex code format, \ - please use format \'#ffffffff\' or \'ffffffff\'." + "invalid hex code format, \ + please use format '#ffff', 'ffff', '#ffffffff' or 'ffffffff'." ); let c = Rgba::::from_str("#ffffff"); assert_eq!( format!("{}", c.err().unwrap()), - "invalid rgba hex code format, \ - please use format \'#ffffffff\' or \'ffffffff\'." + "invalid hex code format, \ + please use format '#ffff', 'ffff', '#ffffffff' or 'ffffffff'." ); }