Rust Serde - 是否可以将可能位于两种不同布局中的 json 数据映射回单个结构?
Rust Serde - Is it possible to map json data the could be in two different layouts back to a single struct?
我试图映射到我的结构的数据有两种格式:
使用card_faces
,当牌面超过一张时:
{
"object": "card",
"id": "some_id",
"lang": "en",
"released_at": "2012-02-03",
"card_faces": [
{
"name": "some_name",
"cost": "5",
"ctype": "some_type",
"colors": [
"R",
"B"
]
},
{
"name": "another_name",
"cost": "",
"ctype": "another_type",
"colors": [
"R",
"B"
]
}
],
"set_code": "some_code"
}
而没有card_faces
,当只有一张人脸时(人脸字段只是放在根中):
{
"object": "card",
"id": "some_id",
"lang": "en",
"released_at": "2012-02-03",
"name": "some_name",
"cost": "5",
"ctype": "some_type",
"colors": [
"R",
"B"
],
"set_code": "some_code"
}
我希望我的结构始终有一个 Vec<CardFace>
字段。类似于:
#[derive(Deserialize)]
struct Card {
object: String,
id: String,
lang: String,
released_at: String,
faces: Vec<CardFace>,
set_code: String,
}
是否可以反序列化这些对象并将面部字段强制转换为所需的格式,或者我是否需要在反序列化之前操作 json?
我会通过中介来做到这一点 enum
:
#[derive(Deserialize)]
#[serde(untagged)]
enum CardTmpDeser {
Card {
object: String,
id: String,
lang: String,
released_at: String,
card_faces: Vec<CardFace>,
set_code: String,
},
SingleCard {
object: String,
id: String,
lang: String,
released_at: String,
name: String,
cost: String,
ctype: String,
colors: Vec<String>,
set_code: String,
},
}
使用 #[serde(untagged)]
属性,您可以透明地反序列化您拥有的两种数据。
现在只需用 #[serde(from = "CardTmpDeser")]
标记您的实际结构:
#[derive(Debug, Deserialize)]
#[serde(from = "CardTmpDeser")]
pub struct Card {
object: String,
id: String,
lang: String,
released_at: String,
card_faces: Vec<CardFace>,
set_code: String,
}
并为 Card
实施 From<CardTmpDeser>
,您就可以开始了! serde
将使用 CardTmpDeser
自动反序列化您的数据,但会透明地将其转换为您的最终类型。
我试图映射到我的结构的数据有两种格式:
使用card_faces
,当牌面超过一张时:
{
"object": "card",
"id": "some_id",
"lang": "en",
"released_at": "2012-02-03",
"card_faces": [
{
"name": "some_name",
"cost": "5",
"ctype": "some_type",
"colors": [
"R",
"B"
]
},
{
"name": "another_name",
"cost": "",
"ctype": "another_type",
"colors": [
"R",
"B"
]
}
],
"set_code": "some_code"
}
而没有card_faces
,当只有一张人脸时(人脸字段只是放在根中):
{
"object": "card",
"id": "some_id",
"lang": "en",
"released_at": "2012-02-03",
"name": "some_name",
"cost": "5",
"ctype": "some_type",
"colors": [
"R",
"B"
],
"set_code": "some_code"
}
我希望我的结构始终有一个 Vec<CardFace>
字段。类似于:
#[derive(Deserialize)]
struct Card {
object: String,
id: String,
lang: String,
released_at: String,
faces: Vec<CardFace>,
set_code: String,
}
是否可以反序列化这些对象并将面部字段强制转换为所需的格式,或者我是否需要在反序列化之前操作 json?
我会通过中介来做到这一点 enum
:
#[derive(Deserialize)]
#[serde(untagged)]
enum CardTmpDeser {
Card {
object: String,
id: String,
lang: String,
released_at: String,
card_faces: Vec<CardFace>,
set_code: String,
},
SingleCard {
object: String,
id: String,
lang: String,
released_at: String,
name: String,
cost: String,
ctype: String,
colors: Vec<String>,
set_code: String,
},
}
使用 #[serde(untagged)]
属性,您可以透明地反序列化您拥有的两种数据。
现在只需用 #[serde(from = "CardTmpDeser")]
标记您的实际结构:
#[derive(Debug, Deserialize)]
#[serde(from = "CardTmpDeser")]
pub struct Card {
object: String,
id: String,
lang: String,
released_at: String,
card_faces: Vec<CardFace>,
set_code: String,
}
并为 Card
实施 From<CardTmpDeser>
,您就可以开始了! serde
将使用 CardTmpDeser
自动反序列化您的数据,但会透明地将其转换为您的最终类型。