flatland-client-ui 0.2.22

Engine-agnostic play client UI state (world grid, input, presentation)
Documentation
//! Shared RGB colors for map presentation (YAML + render backends).

#[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,
    }
}