use std::env;
use std::fmt::Write as _;
use std::fs;
use std::io;
use std::path::Path;
const TEMPLATE_FILES: [&str; 5] = [
"templates/flat_badge_template.svg",
"templates/flat_square_badge_template.svg",
"templates/plastic_badge_template.svg",
"templates/social_badge_template.svg",
"templates/for_the_badge_template.svg",
];
const FONT_TABLES: [(&str, &str); 4] = [
("VERDANA_11_NORMAL", "assets/fonts/verdana-11px-normal.json"),
("HELVETICA_11_BOLD", "assets/fonts/helvetica-11px-bold.json"),
("VERDANA_10_NORMAL", "assets/fonts/verdana-10px-normal.json"),
("VERDANA_10_BOLD", "assets/fonts/verdana-10px-bold.json"),
];
fn main() -> io::Result<()> {
println!("cargo:rerun-if-changed=build.rs");
minify_templates()?;
generate_font_tables()?;
Ok(())
}
fn minify_templates() -> io::Result<()> {
for file in &TEMPLATE_FILES {
println!("cargo:rerun-if-changed={file}");
let path = Path::new(file);
let dest = path.with_extension("min.svg");
let content = fs::read_to_string(path)?;
let min_content = minify_svg(&content);
if fs::read_to_string(&dest).is_ok_and(|existing| existing == min_content) {
continue;
}
fs::write(dest, min_content)?;
}
Ok(())
}
fn minify_svg(content: &str) -> String {
let min_content = content.lines().map(str::trim).collect::<String>();
let min_content = min_content.split_whitespace().collect::<Vec<_>>().join(" ");
min_content.replace(" />", "/>").replace("> <", "><")
}
fn generate_font_tables() -> io::Result<()> {
let out_dir = env::var("OUT_DIR").expect("OUT_DIR is set by cargo");
let mut code = String::from(
"// Generated by build.rs from assets/fonts/*.json. Do not edit.\n\
// Sorted, non-overlapping (lower, upper, width) code point ranges.\n",
);
for (name, path) in &FONT_TABLES {
println!("cargo:rerun-if-changed={path}");
let json = fs::read_to_string(path)?;
let ranges: Vec<(u32, u32, f64)> = serde_json::from_str(&json)
.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e.to_string()))?;
assert!(
ranges.windows(2).all(|w| w[0].1 < w[1].0),
"{path}: font ranges must be sorted and non-overlapping"
);
writeln!(
code,
"pub static {name}: [(u32, u32, f64); {}] = [",
ranges.len()
)
.unwrap();
for (lower, upper, width) in ranges {
writeln!(code, " ({lower}, {upper}, {width:?}),").unwrap();
}
code.push_str("];\n");
}
fs::write(Path::new(&out_dir).join("font_tables.rs"), code)
}