use std::fs;
use std::io::Write;
use std::path::PathBuf;
use flate2::Compression;
use flate2::write::GzEncoder;
fn main() {
let manifest_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
let db_dir = manifest_dir.join("data").join("db");
let out_dir = PathBuf::from(std::env::var("OUT_DIR").expect("OUT_DIR set by cargo"));
println!("cargo:rerun-if-changed=data/db");
println!("cargo:rerun-if-changed=build.rs");
let mut xml_files: Vec<PathBuf> = fs::read_dir(&db_dir)
.unwrap_or_else(|e| panic!("read {}: {e}", db_dir.display()))
.filter_map(|entry| entry.ok().map(|e| e.path()))
.filter(|p| p.is_file() && p.extension().is_some_and(|ext| ext == "xml"))
.collect();
xml_files.sort();
let mut entries = String::new();
for src in &xml_files {
let name = src
.file_name()
.and_then(|n| n.to_str())
.expect("xml filename is valid UTF-8");
let bytes = fs::read(src).unwrap_or_else(|e| panic!("read {}: {e}", src.display()));
let uncompressed_size = bytes.len();
let mut encoder = GzEncoder::new(Vec::new(), Compression::default());
encoder.write_all(&bytes).expect("gzip write");
let compressed = encoder.finish().expect("gzip finish");
let gz_name = format!("{name}.gz");
let gz_path = out_dir.join(&gz_name);
fs::write(&gz_path, &compressed)
.unwrap_or_else(|e| panic!("write {}: {e}", gz_path.display()));
entries.push_str(&format!(
" BundledFile {{ name: {name:?}, uncompressed_size: {uncompressed_size}, gz: include_bytes!(concat!(env!(\"OUT_DIR\"), \"/{gz_name}\")) }},\n",
));
}
let generated = format!(
"// @generated by build.rs — do not edit.\n\
pub struct BundledFile {{\n\
\x20 pub name: &'static str,\n\
\x20 pub uncompressed_size: usize,\n\
\x20 pub gz: &'static [u8],\n\
}}\n\
pub static BUNDLED_DB: &[BundledFile] = &[\n{entries}];\n",
);
let out_file = out_dir.join("bundled_db.rs");
fs::write(&out_file, generated).unwrap_or_else(|e| panic!("write {}: {e}", out_file.display()));
}