Skip to content

Automatic conversion between Protocol Buffers generated types and your Rust types.

Notifications You must be signed in to change notification settings

Ventmere/s2-grpc-utils

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

S2 gRPC Utilities

Automatic conversion between Protocol Buffers generated types and your Rust types.

Usage

See tests/derive.rs

Libraries

  • Protocol Buffers implementation: prost
  • gRPC implementation: tonic

Type Conventions

All Protobuf Types 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::S2ProtoEnum;

  #[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, S2ProtoEnum, PartialEq)]
  #[s2_grpc(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");

About

Automatic conversion between Protocol Buffers generated types and your Rust types.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages