英文:
How to convert a `serde_json::Value ` to a `prost_types::Struct` in Rust?
问题
fn to_struct(json: serde_json::Value) -> prost_types::Struct {
// 如何实现它?
}
有没有用于此目的的 crate?
英文:
fn to_struct(json: serde_json::Value) -> prost_types::Struct {
// How to implement it?
}
Is there any crate to do it?
答案1
得分: 1
以下是您要求的代码部分的翻译:
这不一定需要使用 crate。但是您的类型混合了:并非所有 `serde_json::Value` 都可以转换为 `prost_type::Struct`,因为 `serde_json::Value` 也可以是列表、字符串、布尔值、数字或空值。如果您确实想要转换为结构体,您需要从 `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(),
}
}
但很可能您只需要以下部分:
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 /* 什么? */),
Bool(v) => BoolValue(v),
Number(n) => NumberValue(n.as_f64().expect("无法表示为非 f64 类型的数字")),
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)),
}),
}
}
请注意,这是 Rust 代码,与中文翻译的一部分,用于解释代码的目的和功能。
英文:
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)),
}),
}
}
答案2
得分: 0
https://crates.io/crates/prost-wkt-types 可以生成 prost_wkt_types::Struct
,它支持 Deserialize
trait。
英文:
https://crates.io/crates/prost-wkt-types can generate prost_wkt_types::Struct
, which supports Deserialize
trait.
答案3
得分: 0
在@Caesar的回答基础上,我只想展示如何在serde_json::Value
和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"),
}
}
希望这对你有帮助。
英文:
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"),
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论