gin-tonic offers:
- a protobuf de-/serialization (like
prost) - a replacement for
prost-build) - a
toniccodec implementation - a wrapper for
tonic-buildadding some extra extra features
While all this can be achieved using the mentioned crates; gin-tonic also offers traits for
converting any Rust type into a protobuf wire type. You are asking why?
If you want to pass a UUID via protobuf you likely end up doing:
message Foo {
string my_uuid = 1;
}Using prost-build and tonic-build this will
generate the following Rust struct:
struct Foo {
my_uuid: String,
}As you notice the Rust type here is String, but in your actual code you want to use an actual
uuid::Uuid. Now you have to do a fallible conversion into your code.
gin-tonic solves this by adding options to the protobuf file:
import "gin/proto/gin.proto";
message Foo {
string my_uuid = 1 [(gin_tonic.v1.rust_type) = "uuid::Uuid"];
}Using the gin-tonic code generator this generates the following Rust code:
struct Foo {
my_uuid: uuid::Uuid,
}For the UUID case gin-tonic offers two features:
uuid_string=> proto transport isstring, parsing error is handled within wire type conversionuuid_bytes=> proto transport isbytes, this does not require additional error handling
You can add you own types by implementing the Scalar trait for your type.
gin tonic:
gin_encode time: [269.91 ns 270.22 ns 270.79 ns]
gin_decode time: [658.58 ns 658.75 ns 658.93 ns]
prost:
prost_encode time: [564.87 ns 566.21 ns 568.18 ns]
prost_decode time: [667.34 ns 671.05 ns 675.87 ns]
As you see decoding performance is comparible while encoding is about twice as fast compared to prost 0.13.1.