"type"
我有两个结构,我想用标签作为JSON中的字段来序列化/反序列化,就像这样。
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
struct ThingA {
value: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
struct ThingB {
value: usize,
}
这些按预期序列化。例如,
let a = ThingA { value: 0 };
println!("{}", serde_json::to_string(&a)?);
// This yields the expected result:
// {"type":"ThingA","value":0}
但是,当我尝试添加一个枚举作为结构的联合类型时,我遇到了麻烦。
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
enum Thing {
ThingA(ThingA),
ThingB(ThingB),
}
上面的定义适用于反序列化 JSON,但在序列化期间添加了一个额外的字段。
let json = r#"{"type": "ThingB", "value": 0}"#;
let thing: Thing = serde_json::from_str(json)?;
// Correctly parses to:
// ThingB(ThingB { value: 0 })
println!("{}", serde_json::to_string(&thing)?);
// Incorrectly serializes with an extra "type" field:
// {"type":"ThingB","type":"ThingB","value":0}
更改#[serde(tag = "type")]
为#[serde(untagged)]
onThing
枚举会导致相反的问题:Thing
实例正确序列化,但不再正确解析。
我的目标是让 JSON在反序列化期间{"type": "ThingB", value: 0}
进行评估Thing::ThingB(ThingB {value: 0})
,反之亦然,但前提是我要反序列化为Thing
. 如果我有一个 unwrapped 的ThingB
, like ThingB {value: 0}
,我希望它也可以序列化{"type": "ThingB", value: 0}
。
所以我的问题是:有没有办法分配 serdetag
或untagged
属性,以便它们仅在序列化/反序列化期间应用(类似于 serde's rename
)?如果没有,关于如何实施Serialize
和/或Deserialize
实现我的目标的任何建议?