#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct RgbColor {
pub r: u8,
pub g: u8,
pub b: u8,
}
impl RgbColor {
pub const fn rgb(r: u8, g: u8, b: u8) -> Self {
Self { r, g, b }
}
pub const BLACK: Self = Self::rgb(0, 0, 0);
pub const RED: Self = Self::rgb(128, 0, 0);
pub const GREEN: Self = Self::rgb(0, 128, 0);
pub const YELLOW: Self = Self::rgb(128, 128, 0);
pub const BLUE: Self = Self::rgb(0, 0, 128);
pub const MAGENTA: Self = Self::rgb(128, 0, 128);
pub const CYAN: Self = Self::rgb(0, 128, 128);
pub const DARK_GRAY: Self = Self::rgb(128, 128, 128);
pub const LIGHT_RED: Self = Self::rgb(255, 0, 0);
pub const LIGHT_GREEN: Self = Self::rgb(0, 255, 0);
pub const LIGHT_YELLOW: Self = Self::rgb(255, 255, 0);
pub const LIGHT_BLUE: Self = Self::rgb(0, 0, 255);
pub const LIGHT_MAGENTA: Self = Self::rgb(255, 0, 255);
pub const LIGHT_CYAN: Self = Self::rgb(0, 255, 255);
pub const WHITE: Self = Self::rgb(255, 255, 255);
}
pub fn parse_color(raw: &str) -> Option<RgbColor> {
let s = raw.trim();
if let Some(hex) = s.strip_prefix('#') {
return parse_hex_color(hex);
}
match s.to_ascii_lowercase().as_str() {
"black" => Some(RgbColor::BLACK),
"red" => Some(RgbColor::RED),
"green" => Some(RgbColor::GREEN),
"yellow" => Some(RgbColor::YELLOW),
"blue" => Some(RgbColor::BLUE),
"magenta" => Some(RgbColor::MAGENTA),
"cyan" => Some(RgbColor::CYAN),
"gray" | "grey" | "darkgray" | "darkgrey" => Some(RgbColor::DARK_GRAY),
"lightred" => Some(RgbColor::LIGHT_RED),
"lightgreen" => Some(RgbColor::LIGHT_GREEN),
"lightyellow" => Some(RgbColor::LIGHT_YELLOW),
"lightblue" => Some(RgbColor::LIGHT_BLUE),
"lightmagenta" => Some(RgbColor::LIGHT_MAGENTA),
"lightcyan" => Some(RgbColor::LIGHT_CYAN),
"white" => Some(RgbColor::WHITE),
_ => None,
}
}
fn parse_hex_color(hex: &str) -> Option<RgbColor> {
let expand = |c: u8| -> u8 { (c << 4) | c };
match hex.len() {
3 => {
let r = u8::from_str_radix(&hex[0..1], 16).ok()?;
let g = u8::from_str_radix(&hex[1..2], 16).ok()?;
let b = u8::from_str_radix(&hex[2..3], 16).ok()?;
Some(RgbColor::rgb(expand(r), expand(g), expand(b)))
}
6 => {
let r = u8::from_str_radix(&hex[0..2], 16).ok()?;
let g = u8::from_str_radix(&hex[2..4], 16).ok()?;
let b = u8::from_str_radix(&hex[4..6], 16).ok()?;
Some(RgbColor::rgb(r, g, b))
}
_ => None,
}
}