use std::fs;
use std::path::Path;
use anyhow::Result;
static GENERATED_CODE_HEADER: &str = "
* This file is automatically generated by build.rs.
* Do not edit manually!
* Re-generate with: cargo build
";
pub fn add_generated_code_header(file: &mut syn::File) {
let doc_attr: syn::Attribute = syn::parse_quote! { #![doc = #GENERATED_CODE_HEADER] };
file.attrs.push(doc_attr);
}
pub fn add_ignore_rustfmt(file: &mut syn::File) {
let doc_attr = syn::parse_quote! { #![cfg_attr(any(), rustfmt::skip)] };
file.attrs.push(doc_attr);
}
pub fn add_ignore_clippy(file: &mut syn::File) {
let doc_attr = syn::parse_quote! { #![allow(clippy::all)] };
file.attrs.push(doc_attr);
}
pub fn validate_json_file(
path: &Path,
validator: &jsonschema::Validator,
schema_name: &str,
) -> Result<serde_json::Value> {
let content = std::fs::read_to_string(path)?;
let json: serde_json::Value = serde_json::from_str(&content)
.map_err(|e| anyhow::anyhow!("Failed to parse JSON syntax in {}: {}", path.display(), e))?;
if let Err(e) = validator.validate(&json) {
return Err(anyhow::anyhow!(
"Failed to validate {} against {} schema:\n{}",
path.display(),
schema_name,
e
));
}
Ok(json)
}
pub fn walk_json_files(dir: &Path, process: &mut dyn FnMut(&Path) -> Result<()>) -> Result<()> {
println!("cargo:rerun-if-changed={}", dir.display());
for entry in fs::read_dir(dir)? {
let path = entry?.path();
if path.is_dir() {
walk_json_files(&path, process)?;
} else if path.extension().is_some_and(|ext| ext == "json") {
process(&path)?;
}
}
Ok(())
}