use std::path::Path; use std::path::PathBuf; use protobuf::reflect::MessageDescriptor; use protobuf_codegen::Codegen; use protobuf_codegen::Customize; use protobuf_codegen::CustomizeCallback; fn main() { // let current_dir = std::env::current_dir().unwrap(); let mut codegen = Codegen::new(); codegen.pure(); codegen.include("protobufs"); // get all the .proto files in the protobufs directory using std let proto_files = get_all_proto_paths("protobufs").expect("failed to read protobufs directory"); for proto_file in proto_files { codegen.input(proto_file); } codegen.cargo_out_dir("protobufs"); codegen.customize_callback(GenSerde); codegen.run_from_script(); println!("cargo:rerun-if-changed=protobufs"); println!("cargo:rerun-if-changed=build.rs"); } fn get_all_proto_paths>(dir: P) -> anyhow::Result> { let mut paths = Vec::new(); let proto_files = std::fs::read_dir(dir).expect("failed to read protobufs directory"); for proto_file in proto_files { let proto_file = proto_file?; if proto_file.file_type().unwrap().is_dir() { let sub_paths = get_all_proto_paths(proto_file.path())?; paths.extend(sub_paths); } else { paths.push(proto_file.path()); } } Ok(paths) } struct GenSerde; impl CustomizeCallback for GenSerde { fn message(&self, _message: &MessageDescriptor) -> Customize { // Customize::default().before("#[derive(::serde::Serialize, ::serde::Deserialize)]") Customize::default() } fn enumeration(&self, _enum_type: &protobuf::reflect::EnumDescriptor) -> Customize { Customize::default().before("#[derive(::serde::Serialize, ::serde::Deserialize)]") } // fn field(&self, field: &FieldDescriptor) -> Customize { // // if field.name() == "public_ip" { // // eprintln!("type_name: {:?}", field.proto().type_name()); // // eprintln!("type_: {:?}", field.proto().type_()); // // eprintln!("{:?}", field.proto()); // // } // if field.proto().type_() == Type::TYPE_ENUM { // // `EnumOrUnknown` is not a part of rust-protobuf, so external serializer is needed. // Customize::default().before( // "#[serde(serialize_with = \"crate::protobufs::serialize_enum_or_unknown\", deserialize_with = \"crate::protobufs::deserialize_enum_or_unknown\")]") // // } else if field.name() == "public_ip" { // // Customize::default().before("#[serde(with = \"crate::protobufs::MessageFieldDef\")]") // } else { // Customize::default() // } // } // fn special_field(&self, _message: &MessageDescriptor, _field: &str) -> Customize { // Customize::default().before("#[serde(skip)]") // } }