这个答案早于问题补充的额外要求,但作为单独的问题保留原样。
处理尾随逗号
由于每个闭合括号 }
前存在尾随逗号,提供的输入数据不是有效的 JSON 数据。如果您必须使用尾随逗号,则传统的 serde_json
包不适合您的需求,您可能需要将所有使用 serde_json
的地方替换为支持尾随逗号的包,例如 json5
包。 json5
提供了类似于 serde_json
的 API,因此以下答案仍然有效。
处理可以具有多种类型的字段
可以使用带有 #[serde(untagged)]
属性的 enum
来处理具有多种可能值类型的 JSON 字段,该枚举包含一个 String
或一个 Vec<String>
。有关属性的详细信息,请参见 serde 的官方文档中的枚举表示形式。
完整示例:
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);
}
示例输出:
MyObj { keya: String("some string"), keyb: Vec(["some string", "some string"]) }
MyObj { keya: Vec(["some string", "some string"]), keyb: String("some string") }
See it in action on Rust Playground