我是 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)
有人可以帮忙解决这个问题吗?
首先,你的 JSON 不是 PascalCase 格式。该属性告诉 serde 查找“Comment”和“Data”而不是原始名称。Serde(默认情况下)会跳过所有其他键,并让您知道它没有找到任何所谓的“注释”。JSON 可能是驼峰命名法,但由于所有键都是单个单词,因此我将不使用重命名属性。您可以查看容器属性文档自行决定。
其次,您没有在 Rust 类型中正确表示 JSON 数组。由 表示的数组SubData
很好,因为 serde 会假设它们是按顺序排列的结构成员,但由 表示的数组SubData.pattern
是数组或单个字符串,因此您不能将其直接反序列化为单个类型。这就是未标记枚举StringOrList
正在处理的事情。如果你想让它始终为 a Vec
,你可以使用attributedeserialize_with
或serde_with
crate。
#[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)