Crate tonic_build

Source
Expand description

§tonic-build

Provides code generation for service stubs to use with tonic. For protobuf compilation via prost, use the tonic-prost-build crate.

§Feature flags

  • cleanup-markdown: Enables cleaning up documentation from the generated code. Useful when documentation of the generated code fails cargo test --doc for example. The prost feature must be enabled to use this feature.
  • prost: Enables usage of prost generator (enabled by default).
  • transport: Enables generation of connect method using tonic::transport::Channel (enabled by default).

§Features

Required dependencies

[dependencies]
tonic = "<tonic-version>"
prost = "<prost-version>"

[build-dependencies]
tonic-prost-build = "<tonic-version>"

§Getting Started

For protobuf compilation, use tonic-prost-build in your build.rs file at the root of the binary/library.

You can rely on the defaults via

fn main() -> Result<(), Box<dyn std::error::Error>> {
    tonic_prost_build::compile_protos("proto/service.proto")?;
    Ok(())
}

Or configure the generated code deeper via

fn main() -> Result<(), Box<dyn std::error::Error>> {
   tonic_prost_build::configure()
        .build_server(false)
        .compile_protos(
            &["proto/helloworld/helloworld.proto"],
            &["proto/helloworld"],
        )?;
   Ok(())
}

For further details how to use the generated client/server, see the examples here or the Google APIs example below.

On NixOS, it is better to specify the location of PROTOC and PROTOC_INCLUDE explicitly.

$ export PROTOBUF_LOCATION=$(nix-env -q protobuf --out-path --no-name)
$ export PROTOC=$PROTOBUF_LOCATION/bin/protoc
$ export PROTOC_INCLUDE=$PROTOBUF_LOCATION/include
$ cargo build

The reason being that if prost_build::compile_protos fails to generate the resultant package, the failure is not obvious until the include!(concat!(env!("OUT_DIR"), "/resultant.rs")); fails with No such file or directory error.

§Google APIs example

A good way to use Google API is probably using git submodules.

So suppose in our proto folder we do:

git submodule add https://github.com/googleapis/googleapis

git submodule update --remote

And a bunch of Google proto files in structure will be like this:

├── googleapis
│   └── google
│       ├── api
│       │   ├── annotations.proto
│       │   ├── client.proto
│       │   ├── field_behavior.proto
│       │   ├── http.proto
│       │   └── resource.proto
│       └── pubsub
│           └── v1
│               ├── pubsub.proto
│               └── schema.proto

Then we can generate Rust code via this setup in our build.rs:

fn main() -> Result<(), Box<dyn std::error::Error>> {
    tonic_prost_build::configure()
        .build_server(false)
        //.out_dir("src/google")  // you can change the generated code's location
        .compile_protos(
            &["proto/googleapis/google/pubsub/v1/pubsub.proto"],
            &["proto/googleapis"], // specify the root location to search proto dependencies
        )?;
    Ok(())
}

Then you can reference the generated Rust like this this in your code:

pub mod api {
    tonic::include_proto!("google.pubsub.v1");
}
use api::{publisher_client::PublisherClient, ListTopicsRequest};

Or if you want to save the generated code in your own code base, you can uncomment the line .out_dir(...) above, and in your lib file config a mod like this:

pub mod google {
    #[path = ""]
    pub mod pubsub {
        #[path = "google.pubsub.v1.rs"]
        pub mod v1;
    }
}

See the example here

Modules§

manual
This module provides utilities for generating tonic service stubs and clients purely in Rust without the need of proto files. It also enables you to set a custom Codec if you want to use a custom serialization format other than protobuf.

Structs§

Attributes
Attributes that will be added to mod and struct items.
CodeGenBuilder
Builder for the generic code generation of server and clients.

Traits§

Method
Method generation trait.
Service
Service generation trait.