如何使用 Serde 反序列化包含空值的 JSON 文件?

2024-05-13

我想反序列化化学元素 JSON 文件GitHub 上的 Bowserinator https://github.com/Bowserinator/Periodic-Table-JSON/blob/master/PeriodicTableJSON.json使用塞尔德。为此,我创建了一个包含所有所需字段的结构,并派生了所需的宏:

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Element {
    name: String,
    appearance: String,
    atomic_mass: f64,
    boil: f64, 
    category: String,
    #[serde(default)]
    color: String,
    density: f64,
    discovered_by: String,
    melt: f64, 
    #[serde(default)]
    molar_heat: f64,
    named_by: String,
    number: String,
    period: u32,
    phase: String,
    source: String,
    spectral_img: String,
    summary: String,
    symbol: String,
    xpos: u32,
    ypos: u32,
}

这可以正常工作,直到到达包含“null”值的字段为止。 例如。对于现场"color": null,在氦气中。

我收到的错误消息是{ code: Message("invalid type: unit value, expected a string"), line: 8, column: 17 }对于这个领域。

我尝试过#[serde(default)]宏观。但这仅适用于 JSON 文件中缺少该字段的情况,而不适用于存在null value.

我喜欢使用标准宏进行反序列化,避免对访问者特征进行编程。有什么我想念的技巧吗?


发生反序列化错误是因为结构定义与传入对象不兼容:color场也可以null,以及一个字符串,但赋予该字段类型String强制你的程序总是期望一个字符串。这是默认行为,这是有道理的。请注意String(或其他容器,例如Box) 在 Rust 中不可“为空”。至于一个nullvalue 不会触发默认值,这就是 Serde 的工作原理:如果对象字段不存在,它会起作用,因为您已经添加了默认字段属性。另一方面,字段“颜色”的值为null并不等于根本没有字段。

解决这个问题的一种方法是调整我们的应用程序的规范以接受null | string,如@user25064的答案所指定:

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Element {
    color: Option<String>,
}

另一种方法是为该字段编写我们自己的反序列化例程,它将接受null然后把它变成其他类型的东西String。这可以通过属性来完成#[serde(deserialize_with=...)].

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Element {
    #[serde(deserialize_with="parse_color")]
    color: String,
}

fn parse_color<'de, D>(d: D) -> Result<String, D::Error> where D: Deserializer<'de> {
    Deserialize::deserialize(d)
        .map(|x: Option<_>| {
            x.unwrap_or("black".to_string())
        })
}

也可以看看:

  • 如何区分缺少的反序列化字段和空字段? https://stackoverflow.com/questions/44331037/how-can-i-distinguish-between-a-deserialized-field-that-is-missing-and-one-that
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Serde 反序列化包含空值的 JSON 文件? 的相关文章

随机推荐