# Protobuf code generator for `protobuf` crate This crate is useful mostly from `build.rs` scripts to generate `.rs` files during the build. # How to generate code There are three main ways to generate `.rs` files from `.proto` files: * using `protoc` command line tool and `protoc-gen-rs` plugin * using this crate `Codegen` with pure rust parser * using this crate `Codegen` with `protoc` parser Which one should you use depends on your needs. If you are using non-cargo build system (like Bazel), you might prefer using `protoc-gen-rs` plugin for `protoc`. If you build with `cargo`, you probably want to use `Codegen` from this crate. # Protoc parser vs pure rust parser There are two protobuf parsers which can be plugged into this crate: * `protoc`-based parser (`protoc` is a command like utility from Google protobuf) * pure rust parser (`protobuf-parse` crate) `protoc`-based parser is expected to parse `.proto` files very correctly: all Google's protobuf implementations rely on it. While there are no known bugs in `protobuf-parse`, it is not tested very well. Also `protobuf-parse` does not implement certain rarely used features of `.proto` parser, mostly complex message options specified in `.proto` files. I never saw anyone using them, but you have been warned. Note `protoc` command can be obtained from [`protoc-bin-vendored`](https://docs.rs/protoc-bin-vendored) crate. # Example ```rust // Use this in build.rs protobuf_codegen::Codegen::new() // Use `protoc` parser, optional. .protoc() // Use `protoc-bin-vendored` bundled protoc command, optional. .protoc_path(&protoc_bin_vendored::protoc_bin_path().unwrap()) // All inputs and imports from the inputs must reside in `includes` directories. .includes(&["src/protos"]) // Inputs must reside in some of include paths. .input("src/protos/apple.proto") .input("src/protos/banana.proto") // Specify output directory relative to Cargo output directory. .cargo_out_dir("protos") .run_from_script(); ``` ## How to use `protoc-gen-rs` If you have to. (Note `protoc` can be invoked programmatically with [protoc crate](https://docs.rs/protoc/)) 0) Install protobuf for `protoc` binary. On OS X [Homebrew](https://github.com/Homebrew/brew) can be used: ```sh brew install protobuf ``` On Ubuntu, `protobuf-compiler` package can be installed: ```sh apt-get install protobuf-compiler ``` Protobuf is needed only for code generation, `rust-protobuf` runtime does not use C++ protobuf library. 1) Install `protoc-gen-rs` program (which is `protoc` plugin) It can be installed either from source or with `cargo install protobuf-codegen` command. 2) Add `protoc-gen-rs` to $PATH If you installed it with cargo, it should be ```sh PATH="$HOME/.cargo/bin:$PATH" ``` 3) Generate .rs files: ```sh protoc --rs_out . foo.proto ``` This will generate .rs files in current directory. # Customize generate code Sometimes generated code need to be adjusted, e. g. to have custom derives. rust-protobuf provides two options to do that: * generated `.rs` files contain `@@protoc_insertion_point(...)` markers (similar markers inserts Google's protobuf generator for C++ or Java). Simple script `sed` one-liners can be used to replace these markers with custom annotations. * `Codegen::customize_callback` can be used to patch generated code when invoked from `build.rs` script. # Serde rust-protobuf since version 3 no longer directly supports serde. Rust-protobuf 3 fully supports: * runtime reflection * JSON parsing and printing via [`protobuf-json-mapping`](https://docs.rs/protobuf-json-mapping) Which covers the most of serde use cases. If you still need serde, generic customization callback (see above) can be used to insert `#[serde(...)]` annotations. [Example project](https://github.com/stepancheg/rust-protobuf/tree/master/protobuf-examples/customize-serde) in the rust-protobuf repository demonstrates how to do it.