如何 serialize/deserialize 具有 None 值的地图

How to serialize/deserialize a map with the None values

我需要一个在我的配置中包含 Option 值的地图。但是,serde 似乎忽略了具有 None

的任何对
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use toml;

#[derive(Debug, Serialize, Deserialize)]
struct Config {
    values: HashMap<String, Option<u32>>,
}

fn main() {
    let values = [("foo", Some(5)), ("bar", None)]
        .iter()
        .map(|(name, s)| (name.to_string(), s.clone()))
        .collect();
    let config = Config { values };

    let s = toml::ser::to_string(&config).unwrap();
    println!("{}", s);
}

产生

[values]
foo = 5

反序列化也是如此:我根本无法以任何形式表示 bar: None, 因为 TOML 没有 Nonenull 或类似的概念。

有什么技巧可以做到吗?

我发现最接近的替代方法是使用一个特殊的标记值(您可能会在 Option::unwrap_or 中使用的那个),它作为真实值出现在 TOML 文件中(例如 0 ), 并在序列化时从 Option::None 转换。但是在反序列化时,哨兵值转换为 Option::None 并为我们留下真正的 Option 类型。

Serde 有一个特殊的 #[serde(with = module)] 属性来自定义 ser/de 字段行为,您可以在这里使用它。完整的工作示例是 here.