1#[macro_export]
2macro_rules! unit_enum_from_str {
3 ($iterable_type:ty) => {
4 impl std::str::FromStr for $iterable_type {
5 type Err = $crate::error::Error;
6
7 fn from_str(value: &str) -> $crate::error::Result<$iterable_type> {
8 let lowercase_value = value.to_ascii_lowercase();
9 <$iterable_type as strum::IntoEnumIterator>::iter()
10 .find(|t| t.to_string().to_ascii_lowercase() == lowercase_value)
11 .ok_or_else(|| {
12 anyhow::anyhow!(
13 "could not convert \"{}\" to a valid {}, possible values are [{}].",
14 value,
15 stringify!($iterable_type),
16 <$iterable_type as strum::IntoEnumIterator>::iter()
17 .map(|t| t.to_string())
18 .collect::<Vec<_>>()
19 .join(", ")
20 )
21 })
22 }
23 }
24 };
25}
26
27#[macro_export]
28macro_rules! unit_enum_deserialize {
29 ($iterable_type:ty) => {
30 impl <'de> serde::de::Deserialize<'de> for $iterable_type {
31 fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
32 where
33 D: serde::Deserializer<'de> {
34
35 $crate::paste::paste! {
36
37 struct [<$iterable_type Visitor>];
38
39 impl serde::de::Visitor<'_> for [<$iterable_type Visitor>] {
40
41 type Value = $iterable_type;
42
43 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
44 formatter.write_str(&format!(
45 "one of: {}",
46 <$iterable_type as strum::IntoEnumIterator>::iter()
47 .map(|variant| variant.to_string())
48 .collect::<Vec<_>>()
49 .join(", ")
50 ))
51 }
52
53 fn visit_str<E>(self, v: &str) -> std::result::Result<Self::Value, E>
54 where
55 E: serde::de::Error, {
56 <$iterable_type as std::str::FromStr>::from_str(v).map_err(|from_str_err| {
57 E::custom(from_str_err.to_string())
58 })
59 }
60 }
61
62 deserializer.deserialize_str([<$iterable_type Visitor>])
63 }
64 }
65 }
66 }
67}
68
69pub use {unit_enum_deserialize, unit_enum_from_str};