prost
prost copied to clipboard
Deserializing JSON to prost struct
Hi
I'm experimenting with decoding JSON messages directly to prost generated structs i.e. serde_json::from_value::<MyMsg>(v) and adding the relevant build config to add the serde derives to the generated structs. On the whole it works but some of the incoming messages (I have no control over the schema) have lists that are either missing, "present and empty" or "present and non-empty". Ideally these would be specified as optional repeated but proto3 doesn't support as repeated is inherently optional, as I understand it. But if they are specified as repeated I end up with serde complaining about missing fields.
Any suggestions on how I might fix/workaround this issue?
Thanks
I've been suffered from the same problem for a long time and I found a distasteful temporary solution
- create a file named "des_null_default.rs.in", which content is:
fn deserialize_null_default<'de, D, T>(deserializer: D) -> Result<T, D::Error>
where
T: Default + serde::Deserialize<'de>,
D: serde::Deserializer<'de>,
{
use serde::Deserialize;
let opt = Option::deserialize(deserializer)?;
Ok(opt.unwrap_or_default())
}
deserialize_null_default fills field with std::Default::default() if occurs null, it is an empty vector when referring to the repeated field.
- attach
#[serde(deserialize_with)]to fields byprost_build::Config
let mut config = prost_build::Config::new();
config.field_attribute(".", // change to your field path
"#[serde(deserialize_with = \"deserialize_null_default\")]");
- include "des_null_default.rs.in" and prost generated file:
pub(crate) mod proto {
include!("des_null_default.rs.in");
include!(concat!(
env!("OUT_DIR"),
"/my_proto.rs" // rust file generated by prost
));
}
then, serde will use deserialize_null_default on your fields