use std::path::PathBuf;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let manifest_dir = PathBuf::from(std::env::var("CARGO_MANIFEST_DIR")?);
let protoc_path = protoc_bin_vendored::protoc_bin_path()?;
std::env::set_var("PROTOC", protoc_path);
let mut proto_root = None;
let local_proto = manifest_dir.join("proto").join("volt_api");
if local_proto.exists() {
proto_root = Some(local_proto);
} else {
let legacy_proto = manifest_dir
.join("..") .join("..") .join("..") .join("tdxvolt-core")
.join("src")
.join("volt_api");
if legacy_proto.exists() {
proto_root = Some(legacy_proto);
}
}
let proto_root = match proto_root {
Some(path) => path.canonicalize()?,
None => {
eprintln!("Warning: Proto directory not found. Looked in:");
eprintln!(" - {:?}", manifest_dir.join("proto").join("volt_api"));
eprintln!(
" - {:?}",
manifest_dir
.join("..")
.join("..")
.join("..")
.join("tdxvolt-core")
.join("src")
.join("volt_api")
);
eprintln!("CARGO_MANIFEST_DIR: {:?}", manifest_dir);
eprintln!("Skipping proto generation, using manual proto definitions.");
return Ok(());
}
};
println!("cargo:rerun-if-changed={}", proto_root.display());
eprintln!("Proto root: {:?}", proto_root);
let proto_files = collect_proto_files(&proto_root)?;
if proto_files.is_empty() {
eprintln!("Warning: No .proto files found in {:?}", proto_root);
return Ok(());
}
eprintln!("Found {} proto files", proto_files.len());
for f in &proto_files {
eprintln!(" - {}", f.display());
println!("cargo:rerun-if-changed={}", f.display());
}
tonic_prost_build::configure()
.build_server(false)
.build_client(true)
.build_transport(false)
.btree_map(".")
.type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]")
.type_attribute(".", "#[serde(rename_all = \"snake_case\")]")
.compile_protos(
&proto_files,
&[proto_root], )?;
eprintln!("Proto compilation successful!");
Ok(())
}
fn collect_proto_files(dir: &PathBuf) -> Result<Vec<PathBuf>, Box<dyn std::error::Error>> {
let mut proto_files = Vec::new();
if !dir.is_dir() {
return Ok(proto_files);
}
for entry in std::fs::read_dir(dir)? {
let entry = entry?;
let path = entry.path();
if path.is_dir() {
proto_files.extend(collect_proto_files(&path)?);
} else if path.extension().map(|e| e == "proto").unwrap_or(false) {
proto_files.push(path);
}
}
Ok(proto_files)
}