#protobuf #buffer #proto #generation #protocols #prost #build

build prost-build

Generate Prost annotated Rust types from Protocol Buffers files

36 releases

0.13.3 Sep 21, 2024
0.13.1 Jul 9, 2024
0.12.3 Nov 21, 2023
0.11.9 Apr 12, 2023
0.1.0 Jun 25, 2017

#21 in Build Utils

Download history 937481/week @ 2024-07-28 934676/week @ 2024-08-04 1031022/week @ 2024-08-11 1004069/week @ 2024-08-18 1056596/week @ 2024-08-25 996575/week @ 2024-09-01 1096885/week @ 2024-09-08 988316/week @ 2024-09-15 1119948/week @ 2024-09-22 1127845/week @ 2024-09-29 1167562/week @ 2024-10-06 1174595/week @ 2024-10-13 1199283/week @ 2024-10-20 1084622/week @ 2024-10-27 1188588/week @ 2024-11-03 1183996/week @ 2024-11-10

4,707,156 downloads per month
Used in 1,589 crates (446 directly)

Apache-2.0

450KB
8K SLoC

Documentation Crate

prost-build

prost-build makes it easy to generate Rust code from .proto files as part of a Cargo build. See the crate documentation for examples of how to integrate prost-build into a Cargo project.

License

prost-build is distributed under the terms of the Apache License (Version 2.0).

See LICENSE for details.

Copyright 2017 Dan Burkert


lib.rs:

prost-build compiles .proto files into Rust.

prost-build is designed to be used for build-time code generation as part of a Cargo build-script.

Example

Let's create a small library crate, snazzy, that defines a collection of snazzy new items in a protobuf file.

$ cargo new --lib snazzy && cd snazzy

First, add prost-build and prost as dependencies to Cargo.toml:

$ cargo add --build prost-build
$ cargo add prost

Next, add src/items.proto to the project:

syntax = "proto3";

package snazzy.items;

// A snazzy new shirt!
message Shirt {
    // Label sizes
    enum Size {
        SMALL = 0;
        MEDIUM = 1;
        LARGE = 2;
    }

    // The base color
    string color = 1;
    // The size as stated on the label
    Size size = 2;
}

To generate Rust code from items.proto, we use prost-build in the crate's build.rs build-script:

use std::io::Result;
fn main() -> Result<()> {
    prost_build::compile_protos(&["src/items.proto"], &["src/"])?;
    Ok(())
}

And finally, in lib.rs, include the generated code:

// Include the `items` module, which is generated from items.proto.
// It is important to maintain the same structure as in the proto.
pub mod snazzy {
    pub mod items {
        include!(concat!(env!("OUT_DIR"), "/snazzy.items.rs"));
    }
}

use snazzy::items;

/// Returns a large shirt of the specified color
pub fn create_large_shirt(color: String) -> items::Shirt {
    let mut shirt = items::Shirt::default();
    shirt.color = color;
    shirt.set_size(items::shirt::Size::Large);
    shirt
}

That's it! Run cargo doc to see documentation for the generated code. The full example project can be found on GitHub.

Feature Flags

  • format: Format the generated output. This feature is enabled by default.
  • cleanup-markdown: Clean up Markdown in protobuf docs. Enable this to clean up protobuf files from third parties.

Cleaning up Markdown in code docs

If you are using protobuf files from third parties, where the author of the protobuf is not treating comments as Markdown, or is, but has codeblocks in their docs, then you may need to clean up the documentation in order that cargo test --doc will not fail spuriously, and that cargo doc doesn't attempt to render the codeblocks as Rust code.

To do this, in your Cargo.toml, add features = ["cleanup-markdown"] to the inclusion of the prost-build crate and when your code is generated, the code docs will automatically be cleaned up a bit.

Sourcing protoc

prost-build depends on the Protocol Buffers compiler, protoc, to parse .proto files into a representation that can be transformed into Rust.

The easiest way for prost-build to find protoc is to install it in your PATH. This can be done by following the protoc install instructions. prost-build will search the current path for protoc or protoc.exe.

When protoc is installed in a different location, set PROTOC to the path of the executable. If set, prost-build uses the PROTOC for locating protoc. For example, on a macOS system where Protobuf is installed with Homebrew, set the environment variables to:

PROTOC=/usr/local/bin/protoc

Alternatively, the path to protoc execuatable can be explicitly set via [Config::protoc_executable()].

If prost-build can not find protoc via these methods the compile_protos method will fail.

Compiling protoc from source

To compile protoc from source you can use the protobuf-src crate and set the correct environment variables.

std::env::set_var("PROTOC", protobuf_src::protoc());

// Now compile your proto files via prost-build

Dependencies

~7–17MB
~231K SLoC