aboutsummaryrefslogtreecommitdiff
path: root/README.md
blob: 5f1e2d764b644646485d59074e168f33453f113c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<!-- cargo-sync-readme start -->

# 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-rust` 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-rust` 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-rust`

If you have to.

(Note `protoc` can be invoked programmatically with
[protoc crate](https://docs.rs/protoc/%3E=3.0.0-alpha))

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-rust` program (which is `protoc` plugin)

It can be installed either from source or with `cargo install protobuf-codegen` command.

2) Add `protoc-gen-rust` to $PATH

If you installed it with cargo, it should be

```sh
PATH="$HOME/.cargo/bin:$PATH"
```

3) Generate .rs files:

```sh
protoc --rust_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.

<!-- cargo-sync-readme end -->