#![feature(default_field_values)]
use std::{fmt::Write as _, fs, path::Path};
use strum::IntoEnumIterator;
use tailwind_fuse::AsTailwindClass;
mod manifest;
fn main() {
let root = Path::new(env!("CARGO_MANIFEST_DIR")).join("../..");
let dir = root.join("ts/uikit/src/generated");
fs::create_dir_all(&dir).expect("create generated dir");
for (component, exports) in manifest::manifest() {
let mut out = String::from("// AUTO-GENERATED by `cargo run -p ev_lib_gen` — do not edit.\n\n");
for (i, ts) in exports.iter().enumerate() {
if i > 0 {
out.push('\n');
}
ts.render(&mut out);
}
let path = dir.join(format!("{component}.ts"));
fs::write(&path, out).expect("write generated component file");
println!("wrote {}", path.display());
}
}
enum Ts {
Const {
name: &'static str,
value: &'static str,
},
Table {
name: &'static str,
ty: &'static str,
entries: Vec<(String, String)>,
},
}
impl Ts {
fn render(&self, out: &mut String) {
match self {
Ts::Const { name, value } => writeln!(out, "export const {name} = {value:?};").unwrap(),
Ts::Table { name, ty, entries } => {
writeln!(out, "export const {name} = {{").unwrap();
for (key, class) in entries {
writeln!(out, " {key:?}: {class:?},").unwrap();
}
out.push_str("} as const;\n");
writeln!(out, "export type {ty} = keyof typeof {name};").unwrap();
}
}
}
}
fn table<T>(name: &'static str, ty: &'static str) -> Ts
where
T: IntoEnumIterator + AsRef<str> + AsTailwindClass, {
Ts::Table {
name,
ty,
entries: T::iter().map(|v| (v.as_ref().to_string(), v.as_class().to_string())).collect(),
}
}