synapse_codegen/
build_helper.rs1use crate::{generate_service_code, parser::parse_proto_file_with_includes};
4use anyhow::Result;
5use std::path::{Path, PathBuf};
6
7pub struct CodegenConfig {
9 pub proto_file: PathBuf,
11 pub out_dir: PathBuf,
13 pub module_name: String,
15 pub include_paths: Vec<PathBuf>,
17}
18
19impl CodegenConfig {
20 pub fn from_proto(proto_file: impl AsRef<Path>) -> Self {
22 let proto_file = proto_file.as_ref().to_path_buf();
23 let module_name = proto_file
24 .file_stem()
25 .unwrap()
26 .to_string_lossy()
27 .replace('-', "_");
28
29 Self {
30 proto_file,
31 out_dir: PathBuf::from(std::env::var("OUT_DIR").unwrap()),
32 module_name,
33 include_paths: Vec::new(),
34 }
35 }
36
37 pub fn out_dir(mut self, out_dir: impl AsRef<Path>) -> Self {
39 self.out_dir = out_dir.as_ref().to_path_buf();
40 self
41 }
42
43 pub fn module_name(mut self, name: impl Into<String>) -> Self {
45 self.module_name = name.into();
46 self
47 }
48
49 pub fn include_paths(mut self, paths: &[&str]) -> Self {
51 self.include_paths = paths.iter().map(PathBuf::from).collect();
52 self
53 }
54
55 pub fn generate(self) -> Result<()> {
57 let services = parse_proto_file_with_includes(&self.proto_file, &self.include_paths)?;
59
60 if services.is_empty() {
61 println!(
62 "cargo:warning=No services found in {}",
63 self.proto_file.display()
64 );
65 return Ok(());
66 }
67
68 let mut all_code = String::new();
70 for service in &services {
71 let code = generate_service_code(service)?;
72 all_code.push_str(&code);
73 all_code.push_str("\n\n");
74
75 println!(
76 "cargo:warning=Generated Synapse code for service {}",
77 service.service_name,
78 );
79 }
80
81 let output_file = self
83 .out_dir
84 .join(format!("{}_synapse.rs", self.module_name));
85 std::fs::write(&output_file, all_code)?;
86
87 println!(
88 "cargo:warning=Wrote {} services to {}",
89 services.len(),
90 output_file.display()
91 );
92
93 println!("cargo:rerun-if-changed={}", self.proto_file.display());
95
96 Ok(())
97 }
98}
99
100pub fn generate_synapse_code(proto_file: impl AsRef<Path>) -> Result<()> {
108 CodegenConfig::from_proto(proto_file).generate()
109}