quick-protobuf icon indicating copy to clipboard operation
quick-protobuf copied to clipboard

Example on transpiling multiple .proto files

Open dlazerka opened this issue 4 years ago • 1 comments

All examples and code I see assume there's only one .proto file. What is recommended way to compile .proto to .rs files, if we have thousands of input .proto files?

dlazerka avatar Feb 20 '20 00:02 dlazerka

Hey this is an old issue but here is an example on compiling multiple proto file to rs files.

CLI

  • pb-rs --include . --output_directory src/protos *.proto This will compile all of the protobuf files in the current directory to rs files in the src/protos directory.

Code: Here is an example of my code however there is a problem discovering types in multiple message This will look two parent directories up and then output the files to the src/protos folder.

use pb_rs::{types::FileDescriptor, ConfigBuilder};
use std::path::{Path, PathBuf};
use walkdir::WalkDir;

fn main() {
    let out_dir = PathBuf::from(::std::env::var("CARGO_MANIFEST_DIR").unwrap()).join("src").join("protos");
    let in_dir = PathBuf::from(::std::env::var("CARGO_MANIFEST_DIR").unwrap()).parent().unwrap().parent().unwrap().to_path_buf();
    // Re-run this build.rs if the protos dir changes (i.e. a new file is added)
    // println!("cargo:rerun-if-changed={}", in_dir.to_str().unwrap());

    println!("{} -> {}", in_dir.to_str().unwrap(), out_dir.to_str().unwrap());

    // Find all *.proto files in the `in_dir` and add them to the list of files
    let mut protos = Vec::new();
    let proto_ext = Some(Path::new("proto").as_os_str());
    for entry in WalkDir::new(&in_dir) {
        let path = entry.unwrap().into_path();
        if path.extension() == proto_ext {
            println!("Found {:?}", path.to_str().unwrap());
            // Re-run this build.rs if any of the files in the protos dir change
            // println!("cargo:rerun-if-changed={}", path.to_str().unwrap());
            protos.push(path);
        }
    }

    // Delete all old generated files before re-generating new ones
    if out_dir.exists() {
        std::fs::remove_dir_all(&out_dir).unwrap();
    }

    std::fs::DirBuilder::new().create(&out_dir).unwrap();
    let config_builder = ConfigBuilder::new(&protos, None, Some(&out_dir), &[in_dir]).unwrap();
    FileDescriptor::run(&config_builder.build()).unwrap()
}

HiceS avatar Jun 28 '23 21:06 HiceS