Functional Weave
Code in Python

charts.contrast@1.0.0

impl/rust/contrast_ratio.rs

1,094 bytes · the Rust implementation · view raw

Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.

use super::funejson::Value;  ← the fune runtime: the JSON value the test vectors use; fune build keeps it only where a signature takes one
use super::charts_color_parse_hex::parse_hex;
use super::charts_color_srgb_to_linear::srgb_to_linear;
use super::math_round_float::round_float;  ← from math.round-float ^1.0.0 · built alongside by fune

/// WCAG 2.x relative luminance: linear-light R, G, B weighted 0.2126, 0.7152, 0.0722.
pub fn relative_luminance(hex: &str) -> f64 {
    let c = parse_hex(hex);
    0.2126 * srgb_to_linear(c.r) + 0.7152 * srgb_to_linear(c.g) + 0.0722 * srgb_to_linear(c.b)
}

/// (lighter + 0.05) / (darker + 0.05), unrounded.
pub fn luminance_contrast(a: &str, b: &str) -> f64 {
    let la = relative_luminance(a);
    let lb = relative_luminance(b);
    if la > lb {
        (la + 0.05) / (lb + 0.05)
    } else {
        (lb + 0.05) / (la + 0.05)
    }
}

/// The WCAG 2.x contrast ratio, 1 to 21, rounded to 6 places.
///
/// # Panics
/// Panics if either colour is not a hex colour.
pub fn contrast_ratio(foreground: &str, background: &str) -> f64 {
    round_float(luminance_contrast(foreground, background), 6)
}

pub fn fune_vector(args: &[Value]) -> Value {
    Value::Float(contrast_ratio(args[0].as_str(), args[1].as_str()))
}