我有一些 JSON 文本数据,其字段可以是字符串或字符串数组。以下是四个可能的示例:
{
"keya": "some string",
"keyb": "some string"
}
{
"keya": "some string",
"keyb": ["some string", "some string"]
}
{
"keya": ["some string", "some string"],
"keyb": "some string"
}
{
"keya": ["some string", "some string"],
"keyb": ["some string", "some string"]
}
Run Code Online (Sandbox Code Playgroud)
如何创建一个类型,允许我使用 Serde 反序列化此类 JSON 文本数据?
这个答案早于OP作为评论给出的额外要求,但由于额外的要求使其成为一个单独的问题,因此保持原样。
处理尾随逗号
由于每个右括号之前都存在尾随逗号,问题中提供的输入数据不是有效的 JSON }。如果您必须使用尾随逗号,那么传统的serde_jsoncrate 不适合您的需求,您可能需要将所有用法替换serde_json为支持尾随逗号的 crate,例如crate json5。提供json5了一个类似于serde_json,因此以下答案仍然有效。
处理可以是多种类型的字段
enum处理具有多种可能值类型的 JSON 字段可以使用包含 aString或 a 的Vec<String>和属性来完成#[serde(untagged)]。请参阅枚举表示有关该属性的详细
完整示例:
use serde::{Serialize, Deserialize};
#[derive(Debug, Serialize, Deserialize)]
#[serde(untagged)]
enum StringOrStringVec {
String(String),
Vec(Vec<String>)
}
#[derive(Debug, Serialize, Deserialize)]
struct MyObj {
keya: StringOrStringVec,
keyb: StringOrStringVec,
}
fn main() {
let input_json = r#"
{
"keya": "some string",
"keyb": ["some string", "some string"]
}
"#;
let my_obj: MyObj = serde_json::from_str(input_json).unwrap();
println!("{:?}", my_obj);
let input_json = r#"
{
"keya": ["some string", "some string"],
"keyb": "some string"
}
"#;
let my_obj: MyObj = serde_json::from_str(input_json).unwrap();
println!("{:?}", my_obj);
}
Run Code Online (Sandbox Code Playgroud)
输出示例:
MyObj { keya: String("some string"), keyb: Vec(["some string", "some string"]) }
MyObj { keya: Vec(["some string", "some string"]), keyb: String("some string") }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3555 次 |
| 最近记录: |