macro_rules! impl_string_enum {
($ty:ident, $expecting:literal, $( $s:literal => $variant:ident ),+ $(,)?) => {
impl ::serde::Serialize for $ty {
fn serialize<S: ::serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
s.serialize_str(match self {
$( $ty::$variant => $s, )+
$ty::Other(v) => v.as_str(),
})
}
}
impl<'de> ::serde::Deserialize<'de> for $ty {
fn deserialize<D: ::serde::Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
struct Visitor;
impl ::serde::de::Visitor<'_> for Visitor {
type Value = $ty;
fn expecting(
&self,
f: &mut ::std::fmt::Formatter<'_>,
) -> ::std::fmt::Result {
write!(f, $expecting)
}
fn visit_str<E: ::serde::de::Error>(self, v: &str) -> Result<$ty, E> {
Ok(match v {
$( $s => $ty::$variant, )+
_ => $ty::Other(v.to_owned()),
})
}
}
d.deserialize_str(Visitor)
}
}
impl ::std::fmt::Display for $ty {
fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
f.write_str(match self {
$( $ty::$variant => $s, )+
$ty::Other(v) => v.as_str(),
})
}
}
};
}