fn to_struct(json: serde_json::Value) -> prost_types::Struct {
// How to implement it?
}
Is there any crate to do it?
fn to_struct(json: serde_json::Value) -> prost_types::Struct {
// How to implement it?
}
Is there any crate to do it?
Adding onto @Caesar's answer, I just wanted to show an example of how to go back and forth between serde_json::Value
and prost_types::Value
:
fn to_struct(json: serde_json::Map<String, serde_json::Value>) -> prost_types::Struct {
prost_types::Struct {
fields: json
.into_iter()
.map(|(k, v)| (k, serde_json_to_prost(v)))
.collect(),
}
}
fn serde_json_to_prost(json: serde_json::Value) -> prost_types::Value {
use prost_types::value::Kind::*;
use serde_json::Value::*;
prost_types::Value {
kind: Some(match json {
Null => NullValue(0 /* wat? */),
Bool(v) => BoolValue(v),
Number(n) => NumberValue(n.as_f64().expect("Non-f64-representable number")),
String(s) => StringValue(s),
Array(v) => ListValue(prost_types::ListValue {
values: v.into_iter().map(serde_json_to_prost).collect(),
}),
Object(v) => StructValue(to_struct(v)),
}),
}
}
fn prost_to_serde_json(x: prost_types::Value) -> serde_json::Value {
use prost_types::value::Kind::*;
use serde_json::Value::*;
match x.kind {
Some(x) => match x {
NullValue(_) => Null,
BoolValue(v) => Bool(v),
NumberValue(n) => Number(serde_json::Number::from_f64(n).unwrap()),
StringValue(s) => String(s),
ListValue(lst) => Array(lst.values.into_iter().map(prost_to_serde_json).collect()),
StructValue(v) => Object(
v.fields
.into_iter()
.map(|(k, v)| (k, prost_to_serde_json(v)))
.collect(),
),
},
None => panic!("todo"),
}
}
This is not necessarily something you need a crate for. You do however have your types mixed: Not all serde_json::Value
s can be converted to a prost_type::Struct
, as serde_json::Value
s can also be lists or strings or bools or numbers or null. If you do want to convert to a struct, you'll need to start from a serde_json::Map
:
fn to_struct(json: serde_json::Map<String, serde_json::Value>) -> prost_types::Struct {
prost_types::Struct {
fields: json
.into_iter()
.map(|(k, v)| (k, serde_json_to_prost(v)))
.collect(),
}
}
Likely though, you only need the following
fn serde_json_to_prost(json: serde_json::Value) -> prost_types::Value {
use prost_types::value::Kind::*;
use serde_json::Value::*;
prost_types::Value {
kind: Some(match json {
Null => NullValue(0 /* wat? */),
Bool(v) => BoolValue(v),
Number(n) => NumberValue(n.as_f64().expect("Non-f64-representable number")),
String(s) => StringValue(s),
Array(v) => ListValue(prost_types::ListValue {
values: v.into_iter().map(serde_json_to_prost).collect(),
}),
Object(v) => StructValue(to_struct(v)),
}),
}
}
https://crates.io/crates/prost-wkt-types can generate
prost_wkt_types::Struct
, which supportsDeserialize
trait.