use ishou_tokens::{Rgb, TokenSet};
#[must_use]
pub fn render(t: &TokenSet) -> String {
let c = &t.color;
let mut out = String::new();
out.push_str("# Generated by ishou-render::stylix — DO NOT EDIT\n");
out.push_str("# Source of truth: pleme-io/ishou/crates/ishou-tokens/src/color.rs\n");
out.push_str("# Architecture: pleme-io/theory/THEME-ARCHITECTURE.md\n");
out.push_str("scheme: \"Nord (pleme-io / ishou)\"\n");
out.push_str("author: \"Arctic Ice Studio; mapped by pleme-io ishou\"\n");
push_base(&mut out, "00", c.polar_night_0);
push_base(&mut out, "01", c.polar_night_1);
push_base(&mut out, "02", c.polar_night_2);
push_base(&mut out, "03", c.polar_night_3);
push_base(&mut out, "04", c.snow_storm_0);
push_base(&mut out, "05", c.snow_storm_1);
push_base(&mut out, "06", c.snow_storm_2);
push_base(&mut out, "07", c.frost_0);
push_base(&mut out, "08", c.aurora_red);
push_base(&mut out, "09", c.aurora_orange);
push_base(&mut out, "0A", c.aurora_yellow);
push_base(&mut out, "0B", c.aurora_green);
push_base(&mut out, "0C", c.frost_1);
push_base(&mut out, "0D", c.frost_2);
push_base(&mut out, "0E", c.aurora_purple);
push_base(&mut out, "0F", c.frost_3);
out
}
fn push_base(out: &mut String, slot: &str, rgb: Rgb) {
out.push_str(&format!(
"base{}: \"{:02x}{:02x}{:02x}\"\n",
slot, rgb.r, rgb.g, rgb.b
));
}
#[cfg(test)]
mod tests {
use super::*;
use ishou_tokens::TokenSet;
#[test]
fn output_is_deterministic() {
let t = TokenSet::pleme();
assert_eq!(render(&t), render(&t));
}
#[test]
fn output_contains_all_16_base_slots() {
let out = render(&TokenSet::pleme());
for slot in [
"base00", "base01", "base02", "base03", "base04", "base05",
"base06", "base07", "base08", "base09", "base0A", "base0B",
"base0C", "base0D", "base0E", "base0F",
] {
assert!(out.contains(&format!("{slot}: \"")), "missing {slot}");
}
}
#[test]
fn nord_polar_night_0_lands_at_base00() {
let out = render(&TokenSet::pleme());
assert!(
out.contains("base00: \"2e3440\""),
"base00 must be polar_night_0 (#2e3440); got:\n{out}"
);
}
#[test]
fn nord_snow_storm_1_lands_at_base05_for_foreground_role() {
let out = render(&TokenSet::pleme());
assert!(out.contains("base05: \"e5e9f0\""), "got:\n{out}");
}
#[test]
fn nord_aurora_red_lands_at_base08() {
let out = render(&TokenSet::pleme());
assert!(out.contains("base08: \"bf616a\""), "got:\n{out}");
}
#[test]
fn hex_is_lowercase_unprefixed_to_match_stylix_contract() {
let out = render(&TokenSet::pleme());
for line in out.lines() {
if let Some(rest) = line.strip_prefix("base") {
if let Some(value_part) = rest.split(": ").nth(1) {
let v = value_part.trim_matches('"');
assert_eq!(v.len(), 6, "wrong length: {line}");
assert!(v.chars().all(|c| c.is_ascii_hexdigit() && !c.is_ascii_uppercase()),
"expected lowercase hex without prefix in: {line}");
}
}
}
}
#[test]
fn full_byte_for_byte_canonical_pleme_output() {
let out = render(&TokenSet::pleme());
let expected = "\
# Generated by ishou-render::stylix — DO NOT EDIT
# Source of truth: pleme-io/ishou/crates/ishou-tokens/src/color.rs
# Architecture: pleme-io/theory/THEME-ARCHITECTURE.md
scheme: \"Nord (pleme-io / ishou)\"
author: \"Arctic Ice Studio; mapped by pleme-io ishou\"
base00: \"2e3440\"
base01: \"3b4252\"
base02: \"434c5e\"
base03: \"4c566a\"
base04: \"d8dee9\"
base05: \"e5e9f0\"
base06: \"eceff4\"
base07: \"8fbcbb\"
base08: \"bf616a\"
base09: \"d08770\"
base0A: \"ebcb8b\"
base0B: \"a3be8c\"
base0C: \"88c0d0\"
base0D: \"81a1c1\"
base0E: \"b48ead\"
base0F: \"5e81ac\"
";
assert_eq!(out, expected);
}
}