1 unstable release
0.1.0 | Sep 27, 2022 |
---|
#255 in #protobuf
14KB
435 lines
Protobuf Mapper
Automatic conversion between Protocol Buffers generated types and your Rust types.
Usage
See tests/derive.rs
Libraries
- Protocol Buffers implementation: prost
Type Conventions
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.
JSON value
Rust Type | Protobuf Type |
---|---|
serde_json::Value | google.protobuf.Value |
Timestamp
Rust Type | Protobuf Type |
---|---|
chrono::DateTime<Utc> | google.protobuf.Timestamp |
BigDecimal
Rust Type | Protobuf Type |
---|---|
bigdecimal::BigDecimal | string |
Optional/Nullable Types
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
.
Enumerations
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");
Dependencies
~5MB
~104K SLoC