prost
prost copied to clipboard
Question: Can we support enum-typed fields?
From the README:
Enumerations
All
.proto
enumeration types convert to the Rusti32
type. Additionally, each enumeration type gets a corresponding Rustenum
type, with helper methods to converti32
values to the enum type. Theenum
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.
Given an enum:
enum Foo {
A = 1;
B = 2;
}
Would it be possible to support "open" enums with a special Unknown(i32)
variant like this?
enum Foo {
A,
B,
Unknown(i32),
}
impl From<i32> for Foo {
fn from(i: i32) -> Self {
match i {
1 => Foo::A,
2 => Foo::B,
_ => Foo::Unknown(i),
}
}
}
impl From<&Foo> for i32 {
fn from(f: &Foo) -> Self {
match f {
Foo::A => 1,
Foo::B => 2,
Foo::Unknown(v) => *v,
}
}
}
That would enable enum-typed fields while allowing match
expressions to naturally handle unknown values.
Possible duplicate of #276
That would enable enum-typed fields while allowing match expressions to naturally handle unknown values.
There's an existing way to do. this: use Foo::from_i32
, which returns None
if the i32
is not a known variant.
prost
predates the TryFrom
API, which is why it's a method. We should probably fix that.
Here's my solution:
use num_derive derive all enums : #[derive(FromPrimitive, ToPrimitive)]
.
But you must handwrite all enums in bulid script which is inconvenient.
This would be very convenient when trying to mix Prost with serde. GRPC enums are represented as strings. For example, a failed request might look like:
{
"error": {
"code": 400,
"message": "API key not valid. Please pass a valid API key.",
"status": "INVALID_ARGUMENT",
}
}
Where status is the well known type defined here: https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto (see here for more details on error mapping: https://cloud.google.com/apis/design/errors#http_mapping)
As is, a custom serde deserializer function needs to be implemented for each enum. If prost used a native enum type, all that would be required is a #[serde(rename_all = "SCREAMING_SNAKE_CASE"]
annotation