Automatic conversion between Protocol Buffers generated types and your Rust types.
See tests/derive.rs
- Protocol Buffers implementation: prost
All Protobuf Type
s that have google.protobuf
namespace are Protocol Buffers Well-Known Types. We use prost-types as their Rust representation. Users should not need to interact with types from prost-types
directly.
Rust Type | Protobuf Type |
---|---|
serde_json::Value | google.protobuf.Value |
Rust Type | Protobuf Type |
---|---|
chrono::DateTime<Utc> | google.protobuf.Timestamp |
Rust Type | Protobuf Type |
---|---|
bigdecimal::BigDecimal | string |
In proto3
, all fields are "optional" (in that it is not an error if the sender fails to set them). But, fields are no longer "nullable", in that there's no way to tell the difference between a field being explicitly set to its default value vs. not having been set at all.
To represent a Rust Option<T>
, we use Wrappers.
For scalar types:
Rust Type | Protobuf Type |
---|---|
Option<f32> |
google.protobuf.FloatValue |
Option<f64> |
google.protobuf.DoubleValue |
Option<i64> |
google.protobuf.Int64Value |
Option<u64> |
google.protobuf.UInt64Value |
Option<i32> |
google.protobuf.Int32Value |
Option<u32> |
google.protobuf.UInt32Value |
Option<bool> |
google.protobuf.BoolValue |
Option<String> |
google.protobuf.StringValue |
We don't need special treatment for complex types (structs) because they are always wrapped by Option<...>
. There is no way to define a non-optional complex field in proto3
.
use crate::ProtoEnum;
#[derive(Debug, PartialEq)]
enum EnumProto {
A = 0,
B = 1,
}
impl EnumProto {
fn from_i32(v: i32) -> Option<Self> {
match v {
0 => Some(EnumProto::A),
1 => Some(EnumProto::B),
_ => None,
}
}
}
#[derive(Debug, ProtoEnum, PartialEq)]
#[protobuf_mapper(proto_enum_type = "EnumProto")]
enum EnumModel {
A,
B,
}
assert_eq!(EnumModel::from_i32(1), Some(EnumModel::B));
assert_eq!(EnumModel::B.pack(), EnumProto::B);
assert_eq!(EnumModel::B.get_variant_name(), "B");
assert_eq!(EnumModel::NAME, "EnumModel");