I need a map with the Option
values in my configuration. However, serde
seems to ignore any pairs with the None
value
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);
}
produces
[values]
foo = 5
The same goes for deserializing: I simply cannot represent bar: None
in any form,
since the TOML has no notion of None
or null
or alike.
Are there some tricks to do that?
The closest alternative I have found is to use a special sentinel value (the one you will probably use in Option::unwrap_or
), which appears in the TOML file as the real value (e.g. 0
), and converts from Option::None
on serialization. But on deserialization, the sentinel value converts to Option::None
and leaves us with the real Option
type.
Serde has a special #[serde(with = module)]
attribute to customize the ser/de field behavior, which you can use here. The full working example is here.