1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
|
use quote::quote;
use std::path::PathBuf;
fn main() {
let manifest_dir =
PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set"));
let path = manifest_dir.join("key-package-versions.json");
println!("cargo:rerun-if-changed={}", path.display());
let data: serde_json::Value = serde_json::from_reader(
std::fs::File::open(&path)
.unwrap_or_else(|e| panic!("Failed to open {}: {}", path.display(), e)),
)
.expect("Failed to parse JSON");
let out_dir = PathBuf::from(std::env::var("OUT_DIR").expect("OUT_DIR not set"));
let path = out_dir.join("key_package_versions.rs");
let mut file = std::fs::File::create(&path)
.unwrap_or_else(|e| panic!("Failed to create {}: {}", path.display(), e));
let data_obj = data.as_object().expect("Expected JSON object at root");
for (key, versions) in data_obj {
let versions = versions
.as_object()
.unwrap_or_else(|| panic!("Expected object for key '{}'", key))
.iter()
.map(|(k, v)| {
let version_str = v.as_str()
.unwrap_or_else(|| panic!("Expected string value for key '{}.{}'", key, k));
quote! {
map.insert(#k, #version_str.parse::<debversion::Version>().expect("Invalid version"));
}
})
.collect::<Vec<_>>();
let key = quote::format_ident!("{}_versions", key);
use std::io::Write;
let doc_string = format!(
"A map of package names to their versions for the key: {}",
key
);
let code = quote! {
lazy_static::lazy_static! {
#[doc = #doc_string]
#[allow(non_upper_case_globals)]
pub static ref #key: std::collections::HashMap<&'static str, debversion::Version> = {
let mut map = std::collections::HashMap::new();
#(#versions)*
map
};
}
};
writeln!(file, "{}", code)
.unwrap_or_else(|e| panic!("Failed to write to output file: {}", e));
}
}
|