Skip to content

Commit

Permalink
returns hex conversion error variants explicitly
Browse files Browse the repository at this point in the history
  • Loading branch information
rafaelbeckel committed Aug 25, 2023
1 parent 0612c46 commit 5cac8d4
Showing 1 changed file with 31 additions and 20 deletions.
51 changes: 31 additions & 20 deletions palette/src/rgb/rgb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
}

Expand All @@ -946,15 +946,6 @@ impl From<ParseIntError> 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 {
Expand All @@ -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
),
}
}
}
Expand Down Expand Up @@ -1004,19 +997,27 @@ impl<S> FromStr for Rgb<S, u8> {
let col: Rgb<S, u8> = Rgb::new(red, green, blue);
Ok(col)
}
_ => Err("invalid hex code format".into()),
_ => Err(FromHexError::HexFormatError("invalid hex code format")),
}
}
}

impl<S> FromStr for Rgba<S, u8> {
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<S, u8>`] instance.
fn from_str(hex: &str) -> Result<Self, Self::Err> {
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<S, u8> = 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)?;
Expand All @@ -1025,7 +1026,7 @@ impl<S> FromStr for Rgba<S, u8> {
let col: Rgba<S, u8> = Rgba::new(red, green, blue, alpha);
Ok(col)
}
_ => Err("invalid rgba hex code format".into()),
_ => Err(FromHexError::RgbaHexFormatError("invalid hex code format")),
}
}
}
Expand Down Expand Up @@ -1423,8 +1424,18 @@ mod test {
assert_eq!(c.unwrap(), Rgb::<Srgb, u8>::new(240, 52, 230));
let c = Rgb::<Srgb, u8>::from_str("abc");
assert_eq!(c.unwrap(), Rgb::<Srgb, u8>::new(170, 187, 204));
let c = Rgba::<Srgb, u8>::from_str("#08ff");
assert_eq!(c.unwrap(), Rgba::<Srgb, u8>::new(0, 136, 255, 255));
let c = Rgba::<Srgb, u8>::from_str("08f0");
assert_eq!(c.unwrap(), Rgba::<Srgb, u8>::new(0, 136, 255, 0));
let c = Rgba::<Srgb, u8>::from_str("#da0bce80");
assert_eq!(c.unwrap(), Rgba::<Srgb, u8>::new(218, 11, 206, 128));
let c = Rgba::<Srgb, u8>::from_str("f034e680");
assert_eq!(c.unwrap(), Rgba::<Srgb, u8>::new(240, 52, 230, 128));
let c = Rgba::<Srgb, u8>::from_str("#ffffffff");
assert_eq!(c.unwrap(), Rgba::<Srgb, u8>::new(255, 255, 255, 255));
let c = Rgba::<Srgb, u8>::from_str("#ffff");
assert_eq!(c.unwrap(), Rgba::<Srgb, u8>::new(255, 255, 255, 255));
let c = Rgba::<Srgb, u8>::from_str("#gggggggg");
assert!(c.is_err());
assert_eq!(
Expand All @@ -1434,14 +1445,14 @@ mod test {
let c = Rgba::<Srgb, u8>::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::<Srgb, u8>::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'."
);
}

Expand Down

0 comments on commit 5cac8d4

Please sign in to comment.