1#![macro_use]
2
3macro_rules! serde_strum_unknown {
10 ($name:ident) => {
11 impl AsRef<str> for $name {
12 fn as_ref(&self) -> &str {
13 match self {
14 Self::UNKNOWN(string) => &*string,
15 known => known.into(),
16 }
17 }
18 }
19 impl std::fmt::Display for $name {
20 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
21 self.as_ref().fmt(f)
22 }
23 }
24 impl serde::ser::Serialize for $name {
25 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
26 where
27 S: serde::ser::Serializer,
28 {
29 serializer.serialize_str(self.as_ref())
30 }
31 }
32
33 impl From<&str> for $name {
34 fn from(item: &str) -> Self {
35 item.parse().unwrap()
36 }
37 }
38 impl<'de> serde::de::Deserialize<'de> for $name {
39 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
40 where
41 D: serde::de::Deserializer<'de>,
42 {
43 #[cfg(not(feature = "deny-unknown-enum-variants-strings"))]
44 {
45 <&str>::deserialize(deserializer).map(Into::into)
46 }
47 #[cfg(feature = "deny-unknown-enum-variants-strings")]
48 {
49 <&str>::deserialize(deserializer)
50 .map(Into::into)
51 .and_then(|item| match item {
52 Self::UNKNOWN(unknown) => {
53 if unknown.is_empty() {
54 Ok(Self::UNKNOWN(unknown))
56 } else {
57 Err(serde::de::Error::unknown_variant(
58 &*unknown,
59 <Self as strum::VariantNames>::VARIANTS,
60 ))
61 }
62 }
63 other => Ok(other),
64 })
65 }
66 }
67 }
68 impl_edeserialize!($name);
69 };
70}
71
72macro_rules! arr {
73 (
74 $( #[$attr:meta] )*
75 $v:vis $id:ident $name:ident: [$ty:ty; _] = $value:expr
76 ) => {
77 $( #[$attr] )*
78 $v $id $name: [$ty; $value.len()] = $value;
79 }
80}
81
82macro_rules! newtype_enum {
90 {
91 $( #[$attr:meta] )*
92 $v:vis newtype_enum $name:ident($repr:ty) {
93 $(
94 $( #[$var_attr:meta] )*
95 $var_name:ident = $var_val:expr,
96 )*
97 }
98 } => {
99 $( #[$attr] )*
100 #[derive(Copy, Clone)]
101 #[derive(Hash, PartialEq, Eq, PartialOrd, Ord)]
102 #[repr(transparent)]
103 $v struct $name($v $repr);
104 impl $name {
105 $(
106 $( #[$var_attr] )*
107 $v const $var_name: Self = Self($var_val);
108 )*
109 }
110
111 impl $name {
112 arr!{
113 #[doc = "Array containing all known variants."]
114 pub const ALL_KNOWN: [Self; _] = [
115 $( Self::$var_name, )*
116 ]
117 }
118
119 #[doc = "If this is one of the known variants."]
120 $v const fn is_known(self) -> bool {
121 match self {
122 $(
123 Self::$var_name => true,
124 )*
125 _ => false,
126 }
127 }
128 }
129
130 impl std::convert::From<$name> for $repr {
131 fn from(value: $name ) -> Self {
132 value.0
133 }
134 }
135 impl serde::ser::Serialize for $name {
136 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
137 where
138 S: serde::ser::Serializer,
139 {
140 <$repr>::serialize(&self.0, serializer)
141 }
142 }
143
144 impl std::convert::From<$repr> for $name {
145 fn from(value: $repr ) -> Self {
146 Self(value)
147 }
148 }
149 impl<'de> serde::de::Deserialize<'de> for $name {
150 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
151 where
152 D: serde::de::Deserializer<'de>
153 {
154 #[cfg(not(feature = "deny-unknown-enum-variants-integers"))]
155 {
156 <$repr>::deserialize(deserializer).map(Into::into)
157 }
158 #[cfg(feature = "deny-unknown-enum-variants-integers")]
159 {
160 <$repr>::deserialize(deserializer).map(Into::into)
161 .and_then(|item: Self| {
162 if 0 != item.0 && !item.is_known() {
164 Err(serde::de::Error::custom(format!(
165 "Unknown integer enum variant: {} (\"deny-unknown-enum-variants-integers\" feature is enabled).\nExpected one of the following: {:?}",
166 item, Self::ALL_KNOWN
167 )))
168 }
169 else {
170 Ok(item)
171 }
172 })
173 }
174 }
175 }
176 impl_edeserialize!($name);
177
178 impl std::fmt::Display for $name {
179 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
180 self.0.fmt(f)
181 }
182 }
183 impl std::fmt::Debug for $name {
184 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
185 write!(f, "{}({}{})", stringify!($name), self.0, if self.is_known() { "" } else { "?" })
186 }
187 }
188 }
189}
190
191macro_rules! impl_edeserialize {
192 ($($t:ty),* $(,)?) => {
193 $(
194 #[cfg(feature = "eserde")]
195 impl<'de> eserde::EDeserialize<'de> for $t {
196 fn deserialize_for_errors<D>(deserializer: D) -> Result<(), ()>
197 where
198 D: serde::Deserializer<'de>
199 {
200 <Self as serde::de::Deserialize<'de>>::deserialize(deserializer).map(|_| ()).map_err(|e| {
201 eserde::reporter::ErrorReporter::report(e);
202 })
203 }
204 }
205 )*
206 };
207}