use thiserror::Error;
#[derive(Debug, Error)]
#[non_exhaustive]
pub enum ColorParseError {
#[error("hex color must contain exactly six digits")]
InvalidLength,
#[error("invalid {channel} channel in hex color")]
InvalidChannel {
channel: &'static str,
#[source]
source: std::num::ParseIntError,
},
}
pub fn parse_hex_color(hex: &str) -> Result<[u8; 4], ColorParseError> {
let hex = hex.trim_start_matches('#');
if hex.len() != 6 {
return Err(ColorParseError::InvalidLength);
}
let r = u8::from_str_radix(&hex[0..2], 16)
.map_err(|source| ColorParseError::InvalidChannel { channel: "red", source })?;
let g = u8::from_str_radix(&hex[2..4], 16).map_err(|source| ColorParseError::InvalidChannel {
channel: "green",
source,
})?;
let b = u8::from_str_radix(&hex[4..6], 16).map_err(|source| ColorParseError::InvalidChannel {
channel: "blue",
source,
})?;
Ok([r, g, b, 255])
}
pub fn parse_boolean(s: &str) -> bool {
matches!(s, "1" | "true")
}
pub fn is_portrait(width: u32, height: u32) -> bool {
height > width
}