use ishou_tokens::{Rgb, TokenSet};
use crate::nix_ast::{AttrEntry, NixFile, attrset, str_};
#[must_use]
pub fn render(t: &TokenSet) -> String {
let c = &t.color;
let hex = |rgb: Rgb| format!("#{:02X}{:02X}{:02X}", rgb.r, rgb.g, rgb.b);
let polar = attrset(vec![
AttrEntry::new("night0", str_(hex(c.polar_night_0))),
AttrEntry::new("night1", str_(hex(c.polar_night_1))),
AttrEntry::new("night2", str_(hex(c.polar_night_2))),
AttrEntry::new("night3", str_(hex(c.polar_night_3))),
]);
let snow = attrset(vec![
AttrEntry::new("storm0", str_(hex(c.snow_storm_0))),
AttrEntry::new("storm1", str_(hex(c.snow_storm_1))),
AttrEntry::new("storm2", str_(hex(c.snow_storm_2))),
]);
let frost = attrset(vec![
AttrEntry::new("frost0", str_(hex(c.frost_0))),
AttrEntry::new("frost1", str_(hex(c.frost_1))),
AttrEntry::new("frost2", str_(hex(c.frost_2))),
AttrEntry::new("frost3", str_(hex(c.frost_3))),
]);
let aurora = attrset(vec![
AttrEntry::new("red", str_(hex(c.aurora_red))),
AttrEntry::new("orange", str_(hex(c.aurora_orange))),
AttrEntry::new("yellow", str_(hex(c.aurora_yellow))),
AttrEntry::new("green", str_(hex(c.aurora_green))),
AttrEntry::new("purple", str_(hex(c.aurora_purple))),
]);
let body = attrset(vec![
AttrEntry::new("polar", polar),
AttrEntry::new("snow", snow).with_blank_above(),
AttrEntry::new("frost", frost).with_blank_above(),
AttrEntry::new("aurora", aurora).with_blank_above(),
]);
let file = NixFile::new(
[
"Generated by ishou-render::nix — DO NOT EDIT",
"Source of truth: pleme-io/ishou/crates/ishou-tokens/src/color.rs",
"Architecture: pleme-io/theory/THEME-ARCHITECTURE.md",
"Shape compatible with the legacy",
"`<wrapper>/module/themes/nord/colors.nix` files this output",
"replaces — import the package and consume identically.",
],
body,
);
file.render()
}
#[cfg(test)]
mod tests {
use super::*;
use ishou_tokens::TokenSet;
#[test]
fn deterministic() {
let t = TokenSet::pleme();
assert_eq!(render(&t), render(&t));
}
#[test]
fn matches_legacy_blackmatter_ghostty_colors_nix() {
let out = render(&TokenSet::pleme());
let expected_body = "\
{
polar = {
night0 = \"#2E3440\";
night1 = \"#3B4252\";
night2 = \"#434C5E\";
night3 = \"#4C566A\";
};
snow = {
storm0 = \"#D8DEE9\";
storm1 = \"#E5E9F0\";
storm2 = \"#ECEFF4\";
};
frost = {
frost0 = \"#8FBCBB\";
frost1 = \"#88C0D0\";
frost2 = \"#81A1C1\";
frost3 = \"#5E81AC\";
};
aurora = {
red = \"#BF616A\";
orange = \"#D08770\";
yellow = \"#EBCB8B\";
green = \"#A3BE8C\";
purple = \"#B48EAD\";
};
}
";
assert!(
out.ends_with(expected_body),
"rendered output's body must match the legacy colors.nix exactly:\n--- got ---\n{out}--- expected end ---\n{expected_body}"
);
}
#[test]
fn nord_polar_night_0_lands_at_polar_night0() {
let out = render(&TokenSet::pleme());
assert!(out.contains("night0 = \"#2E3440\""), "got:\n{out}");
}
#[test]
fn header_documents_provenance() {
let out = render(&TokenSet::pleme());
assert!(out.contains("THEME-ARCHITECTURE.md"));
assert!(out.contains("Source of truth"));
}
}