dan*_*woz 3 rust serde serde-json
我有两个结构体,我想将它们序列化/反序列化,并将标签作为"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,
}
Run Code Online (Sandbox Code Playgroud)
这些按预期序列化。例如,
let a = ThingA { value: 0 };
println!("{}", serde_json::to_string(&a)?);
// This yields the expected result:
// {"type":"ThingA","value":0}
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试添加枚举来代替结构的联合类型时,我遇到了麻烦。
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
enum Thing {
ThingA(ThingA),
ThingB(ThingB),
}
Run Code Online (Sandbox Code Playgroud)
上面的定义对于反序列化 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}
Run Code Online (Sandbox Code Playgroud)
更改#[serde(tag = "type")]为#[serde(untagged)]枚举Thing会导致相反的问题:Thing实例正确序列化,但不再正确解析。
我的目标是在反序列化期间获取 JSON{"type": "ThingB", value: 0}进行评估Thing::ThingB(ThingB {value: 0}),反之亦然,但前提是我要反序列化为Thing. 如果我有一个未包装的ThingB,例如ThingB {value: 0},我也希望它能够序列化{"type": "ThingB", value: 0}。
所以我的问题是:有什么方法可以分配 serdetag或untagged属性,以便它们仅在序列化/反序列化期间应用(类似于 serde rename)?如果没有,关于如何实施Serialize和/或Deserialize实现我的目标有什么建议吗?
tag您可以只在枚举中使用Thing,而使其他枚举保持干净:
use serde::{Serialize, Deserialize}; // 1.0.124
use serde_json; // 1.0.64
#[derive(Debug, Clone, Serialize, Deserialize)]
struct ThingA {
value: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
struct ThingB {
value: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type")]
enum Thing {
ThingA(ThingA),
ThingB(ThingB),
}
fn main() {
let json = r#"{"type": "ThingB", "value": 0}"#;
let thing: Thing = serde_json::from_str(json).unwrap();
println!("{}", serde_json::to_string(&thing).unwrap());
}
Run Code Online (Sandbox Code Playgroud)
按照评论中的要求。如果我们想要同时标记(枚举和结构),我们需要使用serde包装器和with. 更多信息可以在这里找到
| 归档时间: |
|
| 查看次数: |
6710 次 |
| 最近记录: |