config: Add ItemOrBool helper for deserializing a bool or a value.

This will enable us to support the new `keystore_dir` field, which can
be either a boolean indicating whether the keystore is disabled or
enabled and initialized with the default keystore dir, or a string which
points to a custom keystore directory (and implies the keystore is
enabled):
```
# use this path, fail if compiled out
# keystore = "/path/to/arti/keystore"
#
# use default path, fail if compiled out
# keystore = true
#
# disable
# keystore = false
```

Part of #891
This commit is contained in:
Gabriela Moldovan 2023-06-23 19:58:17 +01:00
parent c90f9308c5
commit 450fa5c474
2 changed files with 60 additions and 0 deletions

View File

@ -0,0 +1 @@
ADDED: `ItemOrBool`

View File

@ -383,6 +383,31 @@ impl TryFrom<ListenItemSerde> for ListenItem {
}
}
/// A deserializable value or bool.
#[derive(Serialize, Deserialize, Debug)]
#[allow(clippy::exhaustive_enums)] // we will add variants very rarely if ever
#[serde(untagged, bound = "T: Serialize, for<'de2> T: Deserialize<'de2>")]
pub enum ItemOrBool<T>
where
T: std::fmt::Debug + Serialize,
for<'de2> T: Deserialize<'de2>,
{
/// A `T` item.
Item(T),
/// A boolean value
Bool(bool),
}
impl<T> Default for ItemOrBool<T>
where
T: std::fmt::Debug + Serialize,
for<'de2> T: Deserialize<'de2>,
{
fn default() -> Self {
Self::Bool(true)
}
}
#[cfg(test)]
mod test {
// @@ begin test lint list maintained by maint/add_warning @@
@ -407,6 +432,9 @@ mod test {
#[serde(default)]
listen: Option<Listen>,
#[serde(default)]
enabled_or_string: ItemOrBool<String>,
}
#[test]
@ -555,4 +583,35 @@ mod test {
chk_err_1("need actual addr/port", "did not match any variant", "true");
chk_err("did not match any variant", r#"listen = [ [] ]"#);
}
#[test]
fn enabled_or_string() {
use ItemOrBool as IOB;
let chk = |iob: IOB<String>, s| {
let tc: TestConfigFile = toml::from_str(s).expect(s);
assert_eq!(
format!("{:?}", iob),
format!("{:?}", tc.enabled_or_string),
"{:?}",
s
);
};
chk(IOB::Bool(false), r#"enabled_or_string = false"#);
chk(IOB::Bool(true), r#"enabled_or_string = true"#);
chk(
IOB::Item("not a bool".into()),
r#"enabled_or_string = "not a bool""#,
);
let chk_e = |s| {
let tc: Result<TestConfigFile, _> = toml::from_str(s);
let _ = tc.expect_err(s);
};
chk_e(r#"enabled_or_string = 1"#);
chk_e(r#"enabled_or_string = []"#);
chk_e(r#"enabled_or_string = {}"#);
}
}