melib/conf: deserialize ToggleFlag from bool & string
parent
3bc187c570
commit
09dc0a2409
|
@ -122,6 +122,46 @@ pub fn none<T>() -> Option<T> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! named_unit_variant {
|
||||||
|
($variant:ident) => {
|
||||||
|
pub mod $variant {
|
||||||
|
/*
|
||||||
|
pub fn serialize<S>(serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: serde::Serializer,
|
||||||
|
{
|
||||||
|
serializer.serialize_str(stringify!($variant))
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
pub fn deserialize<'de, D>(deserializer: D) -> Result<(), D::Error>
|
||||||
|
where
|
||||||
|
D: serde::Deserializer<'de>,
|
||||||
|
{
|
||||||
|
struct V;
|
||||||
|
impl<'de> serde::de::Visitor<'de> for V {
|
||||||
|
type Value = ();
|
||||||
|
fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||||
|
f.write_str(concat!("\"", stringify!($variant), "\""))
|
||||||
|
}
|
||||||
|
fn visit_str<E: serde::de::Error>(self, value: &str) -> Result<Self::Value, E> {
|
||||||
|
if value == stringify!($variant) {
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(E::invalid_value(serde::de::Unexpected::Str(value), &self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deserializer.deserialize_str(V)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
mod strings {
|
||||||
|
named_unit_variant!(ask);
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Copy, Debug, Clone, PartialEq)]
|
#[derive(Copy, Debug, Clone, PartialEq)]
|
||||||
pub enum ToggleFlag {
|
pub enum ToggleFlag {
|
||||||
Unset,
|
Unset,
|
||||||
|
@ -191,17 +231,25 @@ impl<'de> Deserialize<'de> for ToggleFlag {
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
{
|
{
|
||||||
let s = <String>::deserialize(deserializer);
|
#[derive(Deserialize)]
|
||||||
Ok(match s? {
|
#[serde(untagged)]
|
||||||
s if s.eq_ignore_ascii_case("true") => ToggleFlag::True,
|
pub enum InnerToggleFlag {
|
||||||
s if s.eq_ignore_ascii_case("false") => ToggleFlag::False,
|
Bool(bool),
|
||||||
s if s.eq_ignore_ascii_case("ask") => ToggleFlag::Ask,
|
#[serde(with = "strings::ask")]
|
||||||
s => {
|
Ask,
|
||||||
return Err(serde::de::Error::custom(format!(
|
}
|
||||||
|
let s = <InnerToggleFlag>::deserialize(deserializer);
|
||||||
|
Ok(
|
||||||
|
match s.map_err(|err| {
|
||||||
|
serde::de::Error::custom(format!(
|
||||||
r#"expected one of "true", "false", "ask", found `{}`"#,
|
r#"expected one of "true", "false", "ask", found `{}`"#,
|
||||||
s
|
err
|
||||||
)))
|
))
|
||||||
}
|
})? {
|
||||||
})
|
InnerToggleFlag::Bool(true) => ToggleFlag::True,
|
||||||
|
InnerToggleFlag::Bool(false) => ToggleFlag::False,
|
||||||
|
InnerToggleFlag::Ask => ToggleFlag::Ask,
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue