We are setting up our rust services and using prost-build to bridge between proto <-> rust land. Our proto definitions are in proto3 Lets take the following proto message:
message Test {
string id = 1;
string body = 2;
string maybe_nullable_thing = 3;
}
This generates a struct like so:
pub struct Test {
#[prost(string, tag="1")]
pub id: ::prost::alloc::string::String,
#[prost(string, tag="2")]
pub body: ::prost::alloc::string::String,
#[prost(string, tag="3")]
pub maybe_nullable_thing: ::prost::alloc::string::String,
}
In other languagues where we have tried this, the fields of a proto message are optional by design and can be left out. In the example there can be cases where maybe_nullable_thing
can not be set.
I can work around this issue by using the optional
keyword. Altho I remember that it was not the best practice to do so(maybe I am mistaken?)
In terms of best practice with proto3 and rust in general, is it okay to use the optional
keyword? If I use serde
along with my Test
struct I can see the default values of all the fields begin set to "".to_owned()
(or empty string).
So I am not sure whats the best practice here? Would love to get some pointers on the best way forward here.
Looking at the readme for Tokio's PROST! tool, it appears their advice is to wrap any non-repeated and non-scalar fields, or any optional fields with
Option<T>
. This may or may not be different for prost-build, but it should give you a good reference to what's expected when using proto3 and Rust.In general, however, you should wrap any value you want to be optional in
Option<T>
. This is not a bad practice, this is the default, standard way to represent "maybe nullable things" in Rust.