使用 serde 反序列化动态外部标记值?
Deserialise dynamic externally tagged values with serde?
我遇到了一些数据,我正试图将其转换为与 serde 一起使用的结构。它是一个嵌套字典,其中每个后续条目的键是数据片段的版本号。我无法思考如何将其转换为将读取这些版本的动态数量的 serde 结构。我附上了一个我想出的糟糕例子,但这绝对是错误的。
我不确定我可以使用哪些关键词来搜索这方面的信息。我在文档中找到的一件事是 externally tagged enums 但是我不太确定这对我有帮助。
{
"v0001": {
"id": "a"
// ...
},
"v0002": {
"id": "b"
// ...
}
"v0003": {
"id": "c"
// ...
}
// ...
}
use serde::{Deserialize, Serialize};
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct Data {
pub v0001: Version,
pub v0002: Version,
pub v0003: Version,
// ??!
}
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct Version {
id: String,
}
我最终要做的是加载 json,附加一个新版本并将其重写回 json。
任何 help/thoughts/feedback 都会很棒! :)
在@cdknight 建议使用 HashMap
之后,我意识到根数据类型不必是 struct
。这是我想出的一个可行的解决方案。我改用了 BTreeMap
,这样按键就会井井有条。
type Data = BTreeMap<String, Version>;
#[derive(Debug, Serialize, Deserialize)]
struct Version {
pub id: String,
}
fn main() {
let input = r#"
{
"v0001": {
"id": "a"
},
"v0002": {
"id": "b"
},
"v0003": {
"id": "c"
}
}"#;
let data: Data = serde_json::from_str(input).unwrap();
dbg!(&data);
let vec: Vec<Version> = data.into_values().collect();
dbg!(&vec);
}
输出:
[src/main.rs:106] &data = {
"v0001": Version {
id: "a",
},
"v0002": Version {
id: "b",
},
"v0003": Version {
id: "c",
},
}
[src/main.rs:109] &vec = [
Version {
id: "a",
},
Version {
id: "b",
},
Version {
id: "c",
},
]
我遇到了一些数据,我正试图将其转换为与 serde 一起使用的结构。它是一个嵌套字典,其中每个后续条目的键是数据片段的版本号。我无法思考如何将其转换为将读取这些版本的动态数量的 serde 结构。我附上了一个我想出的糟糕例子,但这绝对是错误的。
我不确定我可以使用哪些关键词来搜索这方面的信息。我在文档中找到的一件事是 externally tagged enums 但是我不太确定这对我有帮助。
{
"v0001": {
"id": "a"
// ...
},
"v0002": {
"id": "b"
// ...
}
"v0003": {
"id": "c"
// ...
}
// ...
}
use serde::{Deserialize, Serialize};
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct Data {
pub v0001: Version,
pub v0002: Version,
pub v0003: Version,
// ??!
}
#[derive(Debug, Default, Serialize, Deserialize)]
pub struct Version {
id: String,
}
我最终要做的是加载 json,附加一个新版本并将其重写回 json。
任何 help/thoughts/feedback 都会很棒! :)
在@cdknight 建议使用 HashMap
之后,我意识到根数据类型不必是 struct
。这是我想出的一个可行的解决方案。我改用了 BTreeMap
,这样按键就会井井有条。
type Data = BTreeMap<String, Version>;
#[derive(Debug, Serialize, Deserialize)]
struct Version {
pub id: String,
}
fn main() {
let input = r#"
{
"v0001": {
"id": "a"
},
"v0002": {
"id": "b"
},
"v0003": {
"id": "c"
}
}"#;
let data: Data = serde_json::from_str(input).unwrap();
dbg!(&data);
let vec: Vec<Version> = data.into_values().collect();
dbg!(&vec);
}
输出:
[src/main.rs:106] &data = {
"v0001": Version {
id: "a",
},
"v0002": Version {
id: "b",
},
"v0003": Version {
id: "c",
},
}
[src/main.rs:109] &vec = [
Version {
id: "a",
},
Version {
id: "b",
},
Version {
id: "c",
},
]