makeover 2.5.2

Shared theme loading for the make-family apps: TOML theme files parsed into intent-based color tokens, with perceptual derivations and WCAG contrast.
Documentation
//! How often a well survives as a fill, per colour depth.
//!
//! `makeover-tui` degrades depth from colour to structure because two surface
//! intents can quantise onto one palette entry. That is measured at ANSI-16.
//! This asks the same question at 256 and at 24 bits, which is what a modern
//! terminal actually offers.

fn main() {
    let mut n = 0;
    let (mut c16, mut c256, mut ctrue) = (0, 0, 0);
    let (mut b16, mut b256) = (0, 0);
    let (mut e16, mut e256) = (0, 0);

    for (id, src) in makeover::embedded_themes() {
        let Ok(table) = src.parse::<toml::Table>() else {
            continue;
        };
        let theme = makeover::ThemeColors {
            meta: makeover::parse_meta(id, &table, false),
            colors: makeover::extract_colors(&table),
        };
        let t = makeover::resolve(&theme);
        let rgb = |k: &str| t.rgb(k).map(|(r, g, b)| makeover::Rgb { r, g, b });
        let (Some(well), Some(raised)) = (rgb("surface-well"), rgb("surface-raised")) else {
            continue;
        };
        let (Some(light), Some(dark)) = (rgb("bevel-light"), rgb("bevel-dark")) else {
            continue;
        };
        n += 1;

        // A fill is invisible when it lands on the same entry as its face.
        if makeover::quantize(well, &makeover::ANSI_16)
            == makeover::quantize(raised, &makeover::ANSI_16)
        {
            c16 += 1;
        }
        if makeover::quantize(well, &makeover::ANSI_256)
            == makeover::quantize(raised, &makeover::ANSI_256)
        {
            c256 += 1;
        }
        if well.r == raised.r && well.g == raised.g && well.b == raised.b {
            ctrue += 1;
        }

        // An edge can also vanish into the face it is drawn on, which is the
        // other half of the degradation and the more common one.
        for (pal, counter) in [
            (&makeover::ANSI_16[..], 0usize),
            (makeover::ANSI_240, 1usize),
        ] {
            let face = makeover::quantize(raised, pal);
            let lit = makeover::quantize(light, pal);
            let shadow = makeover::quantize(dark, pal);
            if lit == face || shadow == face {
                if counter == 0 { e16 += 1 } else { e256 += 1 }
            }
        }

        // A bevel loses its second tone the same way.
        if makeover::quantize(light, &makeover::ANSI_16)
            == makeover::quantize(dark, &makeover::ANSI_16)
        {
            b16 += 1;
        }
        if makeover::quantize(light, &makeover::ANSI_256)
            == makeover::quantize(dark, &makeover::ANSI_256)
        {
            b256 += 1;
        }
    }

    println!("themes measured: {n}\n");
    println!("well collapses onto its face:");
    println!("  ANSI-16    {c16:>3} / {n}");
    println!("  ANSI-256   {c256:>3} / {n}");
    println!("  truecolor  {ctrue:>3} / {n}");
    println!("\nbevel loses its second tone:");
    println!("  ANSI-16    {b16:>3} / {n}");
    println!("  ANSI-256   {b256:>3} / {n}");
    println!("\nat least one bevel edge vanishes into its own face:");
    println!("  ANSI-16    {e16:>3} / {n}");
    println!("  ANSI-256   {e256:>3} / {n}");
}