summaryrefslogtreecommitdiffstats
path: root/third_party/rust/prost/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/prost/README.md')
-rw-r--r--third_party/rust/prost/README.md462
1 files changed, 462 insertions, 0 deletions
diff --git a/third_party/rust/prost/README.md b/third_party/rust/prost/README.md
new file mode 100644
index 0000000000..fc5d87b80d
--- /dev/null
+++ b/third_party/rust/prost/README.md
@@ -0,0 +1,462 @@
+![continuous integration](https://github.com/tokio-rs/prost/workflows/continuous%20integration/badge.svg)
+[![Documentation](https://docs.rs/prost/badge.svg)](https://docs.rs/prost/)
+[![Crate](https://img.shields.io/crates/v/prost.svg)](https://crates.io/crates/prost)
+[![Dependency Status](https://deps.rs/repo/github/tokio-rs/prost/status.svg)](https://deps.rs/repo/github/tokio-rs/prost)
+
+# *PROST!*
+
+`prost` is a [Protocol Buffers](https://developers.google.com/protocol-buffers/)
+implementation for the [Rust Language](https://www.rust-lang.org/). `prost`
+generates simple, idiomatic Rust code from `proto2` and `proto3` files.
+
+Compared to other Protocol Buffers implementations, `prost`
+
+* Generates simple, idiomatic, and readable Rust types by taking advantage of
+ Rust `derive` attributes.
+* Retains comments from `.proto` files in generated Rust code.
+* Allows existing Rust types (not generated from a `.proto`) to be serialized
+ and deserialized by adding attributes.
+* Uses the [`bytes::{Buf, BufMut}`](https://github.com/carllerche/bytes)
+ abstractions for serialization instead of `std::io::{Read, Write}`.
+* Respects the Protobuf `package` specifier when organizing generated code
+ into Rust modules.
+* Preserves unknown enum values during deserialization.
+* Does not include support for runtime reflection or message descriptors.
+
+## Using `prost` in a Cargo Project
+
+First, add `prost` and its public dependencies to your `Cargo.toml`:
+
+```
+[dependencies]
+prost = "0.8"
+# Only necessary if using Protobuf well-known types:
+prost-types = "0.8"
+```
+
+The recommended way to add `.proto` compilation to a Cargo project is to use the
+`prost-build` library. See the [`prost-build` documentation](prost-build) for
+more details and examples.
+
+## Generated Code
+
+`prost` generates Rust code from source `.proto` files using the `proto2` or
+`proto3` syntax. `prost`'s goal is to make the generated code as simple as
+possible.
+
+### Packages
+
+All `.proto` files used with `prost` must contain a
+[`package` specifier][package]. `prost` will translate the Protobuf package into
+a Rust module. For example, given the `package` specifier:
+
+[package]: https://developers.google.com/protocol-buffers/docs/proto#packages
+
+```proto
+package foo.bar;
+```
+
+All Rust types generated from the file will be in the `foo::bar` module.
+
+### Messages
+
+Given a simple message declaration:
+
+```proto
+// Sample message.
+message Foo {
+}
+```
+
+`prost` will generate the following Rust struct:
+
+```rust
+/// Sample message.
+#[derive(Clone, Debug, PartialEq, Message)]
+pub struct Foo {
+}
+```
+
+### Fields
+
+Fields in Protobuf messages are translated into Rust as public struct fields of the
+corresponding type.
+
+#### Scalar Values
+
+Scalar value types are converted as follows:
+
+| Protobuf Type | Rust Type |
+| --- | --- |
+| `double` | `f64` |
+| `float` | `f32` |
+| `int32` | `i32` |
+| `int64` | `i64` |
+| `uint32` | `u32` |
+| `uint64` | `u64` |
+| `sint32` | `i32` |
+| `sint64` | `i64` |
+| `fixed32` | `u32` |
+| `fixed64` | `u64` |
+| `sfixed32` | `i32` |
+| `sfixed64` | `i64` |
+| `bool` | `bool` |
+| `string` | `String` |
+| `bytes` | `Vec<u8>` |
+
+#### Enumerations
+
+All `.proto` enumeration types convert to the Rust `i32` type. Additionally,
+each enumeration type gets a corresponding Rust `enum` type. For example, this
+`proto` enum:
+
+```proto
+enum PhoneType {
+ MOBILE = 0;
+ HOME = 1;
+ WORK = 2;
+}
+```
+
+gets this corresponding Rust enum [1]:
+
+```rust
+pub enum PhoneType {
+ Mobile = 0,
+ Home = 1,
+ Work = 2,
+}
+```
+
+You can convert a `PhoneType` value to an `i32` by doing:
+
+```rust
+PhoneType::Mobile as i32
+```
+
+The `#[derive(::prost::Enumeration)]` annotation added to the generated
+`PhoneType` adds these associated functions to the type:
+
+```rust
+impl PhoneType {
+ pub fn is_valid(value: i32) -> bool { ... }
+ pub fn from_i32(value: i32) -> Option<PhoneType> { ... }
+}
+```
+
+so you can convert an `i32` to its corresponding `PhoneType` value by doing,
+for example:
+
+```rust
+let phone_type = 2i32;
+
+match PhoneType::from_i32(phone_type) {
+ Some(PhoneType::Mobile) => ...,
+ Some(PhoneType::Home) => ...,
+ Some(PhoneType::Work) => ...,
+ None => ...,
+}
+```
+
+Additionally, wherever a `proto` enum is used as a field in a `Message`, the
+message will have 'accessor' methods to get/set the value of the field as the
+Rust enum type. For instance, this proto `PhoneNumber` message that has a field
+named `type` of type `PhoneType`:
+
+```proto
+message PhoneNumber {
+ string number = 1;
+ PhoneType type = 2;
+}
+```
+
+will become the following Rust type [1] with methods `type` and `set_type`:
+
+```rust
+pub struct PhoneNumber {
+ pub number: String,
+ pub r#type: i32, // the `r#` is needed because `type` is a Rust keyword
+}
+
+impl PhoneNumber {
+ pub fn r#type(&self) -> PhoneType { ... }
+ pub fn set_type(&mut self, value: PhoneType) { ... }
+}
+```
+
+Note that the getter methods will return the Rust enum's default value if the
+field has an invalid `i32` value.
+
+The `enum` type isn't used directly as a field, because the Protobuf spec
+mandates that enumerations values are 'open', and decoding unrecognized
+enumeration values must be possible.
+
+[1] Annotations have been elided for clarity. See below for a full example.
+
+#### Field Modifiers
+
+Protobuf scalar value and enumeration message fields can have a modifier
+depending on the Protobuf version. Modifiers change the corresponding type of
+the Rust field:
+
+| `.proto` Version | Modifier | Rust Type |
+| --- | --- | --- |
+| `proto2` | `optional` | `Option<T>` |
+| `proto2` | `required` | `T` |
+| `proto3` | default | `T` |
+| `proto2`/`proto3` | repeated | `Vec<T>` |
+
+#### Map Fields
+
+Map fields are converted to a Rust `HashMap` with key and value type converted
+from the Protobuf key and value types.
+
+#### Message Fields
+
+Message fields are converted to the corresponding struct type. The table of
+field modifiers above applies to message fields, except that `proto3` message
+fields without a modifier (the default) will be wrapped in an `Option`.
+Typically message fields are unboxed. `prost` will automatically box a message
+field if the field type and the parent type are recursively nested in order to
+avoid an infinite sized struct.
+
+#### Oneof Fields
+
+Oneof fields convert to a Rust enum. Protobuf `oneof`s types are not named, so
+`prost` uses the name of the `oneof` field for the resulting Rust enum, and
+defines the enum in a module under the struct. For example, a `proto3` message
+such as:
+
+```proto
+message Foo {
+ oneof widget {
+ int32 quux = 1;
+ string bar = 2;
+ }
+}
+```
+
+generates the following Rust[1]:
+
+```rust
+pub struct Foo {
+ pub widget: Option<foo::Widget>,
+}
+pub mod foo {
+ pub enum Widget {
+ Quux(i32),
+ Bar(String),
+ }
+}
+```
+
+`oneof` fields are always wrapped in an `Option`.
+
+[1] Annotations have been elided for clarity. See below for a full example.
+
+### Services
+
+`prost-build` allows a custom code-generator to be used for processing `service`
+definitions. This can be used to output Rust traits according to an
+application's specific needs.
+
+### Generated Code Example
+
+Example `.proto` file:
+
+```proto
+syntax = "proto3";
+package tutorial;
+
+message Person {
+ string name = 1;
+ int32 id = 2; // Unique ID number for this person.
+ string email = 3;
+
+ enum PhoneType {
+ MOBILE = 0;
+ HOME = 1;
+ WORK = 2;
+ }
+
+ message PhoneNumber {
+ string number = 1;
+ PhoneType type = 2;
+ }
+
+ repeated PhoneNumber phones = 4;
+}
+
+// Our address book file is just one of these.
+message AddressBook {
+ repeated Person people = 1;
+}
+```
+
+and the generated Rust code (`tutorial.rs`):
+
+```rust
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Person {
+ #[prost(string, tag="1")]
+ pub name: ::prost::alloc::string::String,
+ /// Unique ID number for this person.
+ #[prost(int32, tag="2")]
+ pub id: i32,
+ #[prost(string, tag="3")]
+ pub email: ::prost::alloc::string::String,
+ #[prost(message, repeated, tag="4")]
+ pub phones: ::prost::alloc::vec::Vec<person::PhoneNumber>,
+}
+/// Nested message and enum types in `Person`.
+pub mod person {
+ #[derive(Clone, PartialEq, ::prost::Message)]
+ pub struct PhoneNumber {
+ #[prost(string, tag="1")]
+ pub number: ::prost::alloc::string::String,
+ #[prost(enumeration="PhoneType", tag="2")]
+ pub r#type: i32,
+ }
+ #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
+ #[repr(i32)]
+ pub enum PhoneType {
+ Mobile = 0,
+ Home = 1,
+ Work = 2,
+ }
+}
+/// Our address book file is just one of these.
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct AddressBook {
+ #[prost(message, repeated, tag="1")]
+ pub people: ::prost::alloc::vec::Vec<Person>,
+}
+```
+
+## Accessing the `protoc` `FileDescriptorSet`
+
+The `prost_build::Config::file_descriptor_set_path` option can be used to emit a file descriptor set
+during the build & code generation step. When used in conjunction with the `std::include_bytes`
+macro and the `prost_types::FileDescriptorSet` type, applications and libraries using Prost can
+implement introspection capabilities requiring details from the original `.proto` files.
+
+## Using `prost` in a `no_std` Crate
+
+`prost` is compatible with `no_std` crates. To enable `no_std` support, disable
+the `std` features in `prost` and `prost-types`:
+
+```
+[dependencies]
+prost = { version = "0.6", default-features = false, features = ["prost-derive"] }
+# Only necessary if using Protobuf well-known types:
+prost-types = { version = "0.6", default-features = false }
+```
+
+Additionally, configure `prost-build` to output `BTreeMap`s instead of `HashMap`s
+for all Protobuf `map` fields in your `build.rs`:
+
+```rust
+let mut config = prost_build::Config::new();
+config.btree_map(&["."]);
+```
+
+When using edition 2015, it may be necessary to add an `extern crate core;`
+directive to the crate which includes `prost`-generated code.
+
+## Serializing Existing Types
+
+`prost` uses a custom derive macro to handle encoding and decoding types, which
+means that if your existing Rust type is compatible with Protobuf types, you can
+serialize and deserialize it by adding the appropriate derive and field
+annotations.
+
+Currently the best documentation on adding annotations is to look at the
+generated code examples above.
+
+### Tag Inference for Existing Types
+
+Prost automatically infers tags for the struct.
+
+Fields are tagged sequentially in the order they
+are specified, starting with `1`.
+
+You may skip tags which have been reserved, or where there are gaps between
+sequentially occurring tag values by specifying the tag number to skip to with
+the `tag` attribute on the first field after the gap. The following fields will
+be tagged sequentially starting from the next number.
+
+```rust
+use prost;
+use prost::{Enumeration, Message};
+
+#[derive(Clone, PartialEq, Message)]
+struct Person {
+ #[prost(string, tag = "1")]
+ pub id: String, // tag=1
+ // NOTE: Old "name" field has been removed
+ // pub name: String, // tag=2 (Removed)
+ #[prost(string, tag = "6")]
+ pub given_name: String, // tag=6
+ #[prost(string)]
+ pub family_name: String, // tag=7
+ #[prost(string)]
+ pub formatted_name: String, // tag=8
+ #[prost(uint32, tag = "3")]
+ pub age: u32, // tag=3
+ #[prost(uint32)]
+ pub height: u32, // tag=4
+ #[prost(enumeration = "Gender")]
+ pub gender: i32, // tag=5
+ // NOTE: Skip to less commonly occurring fields
+ #[prost(string, tag = "16")]
+ pub name_prefix: String, // tag=16 (eg. mr/mrs/ms)
+ #[prost(string)]
+ pub name_suffix: String, // tag=17 (eg. jr/esq)
+ #[prost(string)]
+ pub maiden_name: String, // tag=18
+}
+
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Enumeration)]
+pub enum Gender {
+ Unknown = 0,
+ Female = 1,
+ Male = 2,
+}
+```
+
+## FAQ
+
+1. **Could `prost` be implemented as a serializer for [Serde](https://serde.rs/)?**
+
+ Probably not, however I would like to hear from a Serde expert on the matter.
+ There are two complications with trying to serialize Protobuf messages with
+ Serde:
+
+ - Protobuf fields require a numbered tag, and currently there appears to be no
+ mechanism suitable for this in `serde`.
+ - The mapping of Protobuf type to Rust type is not 1-to-1. As a result,
+ trait-based approaches to dispatching don't work very well. Example: six
+ different Protobuf field types correspond to a Rust `Vec<i32>`: `repeated
+ int32`, `repeated sint32`, `repeated sfixed32`, and their packed
+ counterparts.
+
+ But it is possible to place `serde` derive tags onto the generated types, so
+ the same structure can support both `prost` and `Serde`.
+
+2. **I get errors when trying to run `cargo test` on MacOS**
+
+ If the errors are about missing `autoreconf` or similar, you can probably fix
+ them by running
+
+ ```
+ brew install automake
+ brew install libtool
+ ```
+
+## License
+
+`prost` is distributed under the terms of the Apache License (Version 2.0).
+
+See [LICENSE](LICENSE) for details.
+
+Copyright 2017 Dan Burkert