use std::fmt;
use std::str::FromStr;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Color {
pub r: u8,
pub g: u8,
pub b: u8,
pub a: u8,
}
impl Color {
pub const fn rgba(r: u8, g: u8, b: u8, a: u8) -> Self {
Self { r, g, b, a }
}
pub const fn from_rgba_u32(v: u32) -> Self {
Self {
r: (v >> 24) as u8,
g: (v >> 16) as u8,
b: (v >> 8) as u8,
a: v as u8,
}
}
pub fn to_skia(self) -> tiny_skia::Color {
tiny_skia::Color::from_rgba8(self.r, self.g, self.b, self.a)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ParseColorError(String);
impl fmt::Display for ParseColorError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"invalid color {:?}: expected #RRGGBB or #RRGGBBAA",
self.0
)
}
}
impl std::error::Error for ParseColorError {}
impl FromStr for Color {
type Err = ParseColorError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let hex = s.strip_prefix('#').unwrap_or(s);
let err = || ParseColorError(s.to_owned());
let word = match hex.len() {
6 => (u32::from_str_radix(hex, 16).map_err(|_| err())? << 8) | 0xFF,
8 => u32::from_str_radix(hex, 16).map_err(|_| err())?,
_ => return Err(err()),
};
Ok(Self::from_rgba_u32(word))
}
}