use std::env;
use std::fs;
use std::path::{Path, PathBuf};
fn main() {
let certs_dir = "certificates";
println!("cargo:rerun-if-changed={}", certs_dir);
let out_dir = env::var("OUT_DIR").unwrap();
let mut mod_file_content = String::new();
mod_file_content.push_str("// Auto-generated certificate modules\n\n");
let entries = match fs::read_dir(certs_dir) {
Ok(entries) => entries,
Err(e) => {
eprintln!("Warning: Failed to read certificates directory: {}", e);
let mod_path = Path::new(&out_dir).join("cert_modules.rs");
fs::write(&mod_path, "// No certificates found").unwrap();
return;
}
};
for entry in entries.flatten() {
let path = entry.path();
if path.is_file() && path.extension().is_some_and(|ext| ext == "pem") {
if let Some(module_name) = generate_module_for_pem(&path, &out_dir) {
mod_file_content.push_str(&format!("pub mod {};\n", module_name));
}
}
}
let mod_path = Path::new(&out_dir).join("certificates.rs");
fs::write(&mod_path, mod_file_content).expect("Failed to write module index file");
}
fn generate_module_for_pem(path: &PathBuf, out_dir: &str) -> Option<String> {
let pem_content = match fs::read_to_string(path) {
Ok(content) => content,
Err(e) => {
eprintln!("Warning: Failed to read PEM file {:?}: {}", path, e);
return None;
}
};
let module_name = path
.file_stem()
.and_then(|s| s.to_str())
.unwrap_or("unknown")
.to_lowercase()
.replace(['-', '.', ' '], "_");
let module_content = format!(
"// Auto-generated from {:?}\n\n\
/// Certificate data from {:?}\n\
pub const CA_PEM: &str = r###\"{}\"###;\n",
path.file_name().unwrap_or_default(),
path.file_name().unwrap_or_default(),
pem_content
);
let module_path = Path::new(out_dir).join(format!("{}.rs", module_name));
match fs::write(&module_path, module_content) {
Ok(_) => Some(module_name),
Err(e) => {
eprintln!(
"Warning: Failed to write module file {:?}: {}",
module_path, e
);
None
}
}
}