lingxia-platform 0.18.0

Platform abstraction layer for LingXia framework (Android, iOS, HarmonyOS)
Documentation
use crate::traits::app_runtime::DesktopBannerBackground;

impl DesktopBannerBackground {
    pub fn parse(value: &str) -> Result<Self, String> {
        let value = value.trim();
        if value.is_empty() || value.eq_ignore_ascii_case("system") {
            return Ok(Self::System);
        }
        if value.eq_ignore_ascii_case("light") {
            return Ok(Self::Light);
        }
        if value.eq_ignore_ascii_case("dark") {
            return Ok(Self::Dark);
        }
        parse_css_color(value)
            .map(|(r, g, b, a)| Self::Color { r, g, b, a })
            .ok_or_else(|| {
                "banner background must be system, light, dark, or #RGB/#RRGGBB/#RRGGBBAA".into()
            })
    }

    pub fn as_ffi(&self) -> String {
        match self {
            Self::System => String::new(),
            Self::Light => "light".into(),
            Self::Dark => "dark".into(),
            Self::Color { r, g, b, a } if *a == 255 => format!("#{r:02x}{g:02x}{b:02x}"),
            Self::Color { r, g, b, a } => format!("#{r:02x}{g:02x}{b:02x}{a:02x}"),
        }
    }

    pub fn prefers_dark_content(&self) -> bool {
        match self {
            Self::Light => true,
            Self::Dark | Self::System => false,
            Self::Color { r, g, b, .. } => relative_luminance(*r, *g, *b) > 0.55,
        }
    }
}

fn parse_css_color(value: &str) -> Option<(u8, u8, u8, u8)> {
    let hex = value.strip_prefix('#')?;
    let digits = hex.as_bytes();
    let nibble = |byte| match byte {
        b'0'..=b'9' => Some(byte - b'0'),
        b'a'..=b'f' => Some(byte - b'a' + 10),
        b'A'..=b'F' => Some(byte - b'A' + 10),
        _ => None,
    };
    let pair = |hi, lo| Some(nibble(hi)? * 16 + nibble(lo)?);
    match digits {
        [r, g, b] => Some((nibble(*r)? * 17, nibble(*g)? * 17, nibble(*b)? * 17, 255)),
        [r1, r2, g1, g2, b1, b2] => Some((pair(*r1, *r2)?, pair(*g1, *g2)?, pair(*b1, *b2)?, 255)),
        [r1, r2, g1, g2, b1, b2, a1, a2] => Some((
            pair(*r1, *r2)?,
            pair(*g1, *g2)?,
            pair(*b1, *b2)?,
            pair(*a1, *a2)?,
        )),
        _ => None,
    }
}

fn relative_luminance(r: u8, g: u8, b: u8) -> f32 {
    0.2126 * (r as f32 / 255.0) + 0.7152 * (g as f32 / 255.0) + 0.0722 * (b as f32 / 255.0)
}