如何使用 serde 在 Rust 中解析这个 JSON 文件?

Pra*_*rad 2 json rust serde

我是 Rust 新手。我正在尝试解析 JSON 文件并将数据存储为 Rust 中的对象。

JSON 文件如下所示:

{
"comment": ["some comments"],
"data": [
    ["name", "line 1"],
    ["name", ["line 1", "line 2"]],
    ......
    ["name", "line 1"]
]
//(The line where the error is coming)

}
Run Code Online (Sandbox Code Playgroud)

我做了这样的结构:

#[derive(Debug, Deserialize)]
struct my_data {
    comment: String,
    data: Vec<sub_data>,
}
#[derive(Debug, Deserialize)]
struct sub_data {
    name: String, 
    pattern: Vec<String>,
}
Run Code Online (Sandbox Code Playgroud)

然后我尝试了这段代码,但出现错误:

Error("missing field `Comment`", line: 1381, column: 1)',
Run Code Online (Sandbox Code Playgroud)

代码:

pub fn read_json () {
    let path = "./src/my_file.json";
    let data = fs::read_to_string(path).expect("Unable to read file");
    let obj: my_data = serde_json::from_str(&data).expect("Unable to parse");
    println!("{:?}", obj);
    return
}
Run Code Online (Sandbox Code Playgroud)

有人可以帮忙解决这个问题吗?

dre*_*ato 5

首先,你的 JSON 不是 PascalCase 格式。该属性告诉 serde 查找“Comment”和“Data”而不是原始名称。Serde(默认情况下)会跳过所有其他键,并让您知道它没有找到任何所谓的“注释”。JSON 可能是驼峰命名法,但由于所有键都是单个单词,因此我将不使用重命名属性。您可以查看容器属性文档自行决定。

其次,您没有在 Rust 类型中正确表示 JSON 数组。由 表示的数组SubData很好,因为 serde 会假设它们是按顺序排列的结构成员,但由 表示的数组SubData.pattern是数组或单个字符串,因此您不能将其直接反序列化为单个类型。这就是未标记枚举StringOrList正在处理的事情。如果你想让它始终为 a Vec,你可以使用attributedeserialize_withserde_withcrate

#[derive(Debug, Deserialize)]
struct MyData {
    comment: Vec<String>,
    data: Vec<SubData>,
}

#[derive(Debug, Deserialize)]
struct SubData {
    name: String, 
    pattern: StringOrList,
}

#[derive(Debug, Deserialize)]
#[serde(untagged)]
enum StringOrList {
    String(String),
    List(Vec<String>),
}
Run Code Online (Sandbox Code Playgroud)