#![allow(
clippy::disallowed_types,
clippy::disallowed_methods,
clippy::expect_used,
clippy::unwrap_used,
clippy::indexing_slicing
)]
use std::{
path::{Path, PathBuf},
process::Command,
};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let out_dir = PathBuf::from(std::env::var("OUT_DIR")?);
let fds_path = out_dir.join("obs_proto.fds");
let fds_tmp = out_dir.join("obs_proto.fds.tmp");
println!("cargo:rerun-if-changed=proto");
println!("cargo:rerun-if-changed=build.rs");
let protoc = std::env::var("PROTOC").unwrap_or_else(|_| "protoc".to_string());
let proto_files = [
"proto/obs/v1/enums.proto",
"proto/obs/v1/options.proto",
"proto/obs/v1/envelope.proto",
"proto/obs/v1/builtin.proto",
"proto/obs/runtime/v1/self_events.proto",
];
let status = Command::new(&protoc)
.arg("--proto_path=proto")
.arg("--include_imports")
.arg(format!("--descriptor_set_out={}", fds_tmp.display()))
.args(proto_files)
.status()?;
if !status.success() {
return Err(format!("protoc failed (status {status})").into());
}
write_if_changed(&fds_tmp, &fds_path)?;
buffa_build::Config::new()
.files(
proto_files
.iter()
.map(|p| p.trim_start_matches("proto/"))
.collect::<Vec<_>>()
.iter()
.map(PathBuf::from)
.collect::<Vec<_>>()
.as_slice(),
)
.descriptor_set(&fds_path)
.include_file("mod.rs")
.compile()?;
println!("cargo:rustc-env=OBS_PROTO_FDS={}", fds_path.display());
Ok(())
}
fn write_if_changed(src: &Path, dst: &Path) -> std::io::Result<()> {
let new = std::fs::read(src)?;
let changed = match std::fs::read(dst) {
Ok(existing) => existing != new,
Err(e) if e.kind() == std::io::ErrorKind::NotFound => true,
Err(e) => return Err(e),
};
if changed {
std::fs::rename(src, dst)?;
} else {
std::fs::remove_file(src)?;
}
Ok(())
}