1#![no_std]
46#![allow(clippy::unnecessary_cast)]
47#![warn(missing_docs)]
48use core::fmt;
49use serde::{
50 de::{self, Unexpected, Visitor},
51 Deserialize, Deserializer, Serialize, Serializer,
52};
53
54#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Default)]
58pub struct ConstBool<const V: bool>;
59
60impl<const V: bool> Serialize for ConstBool<V> {
61 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
62 where
63 S: Serializer,
64 {
65 serializer.serialize_bool(V)
66 }
67}
68
69impl<'de, const V: bool> Deserialize<'de> for ConstBool<V> {
70 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
71 where
72 D: Deserializer<'de>,
73 {
74 deserializer.deserialize_bool(ConstBoolVisitor::<V>)
75 }
76}
77
78struct ConstBoolVisitor<const V: bool>;
79
80impl<'de, const V: bool> Visitor<'de> for ConstBoolVisitor<V> {
81 type Value = ConstBool<V>;
82 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
83 write!(formatter, "{V}")
84 }
85 fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
86 where
87 E: de::Error,
88 {
89 if v == V {
90 Ok(ConstBool::<V>)
91 } else {
92 Err(E::invalid_value(Unexpected::Bool(v), &self))
93 }
94 }
95}
96
97macro_rules! declare_int {
98 ($($type:ty => $struct:ident $visitor:ident $ser_func:ident $deser_func:ident),* $(,)?) => {
99 $(
100 #[doc = concat!("A const `", stringify!($type), "`.")]
101 #[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Default)]
104 pub struct $struct<const V: $type>;
105
106 impl<const V: $type> Serialize for $struct<V> {
107 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
108 where
109 S: Serializer,
110 {
111 serializer.$ser_func(V)
112 }
113 }
114
115 impl<'de, const V: $type> Deserialize<'de> for $struct<V> {
116 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
117 where
118 D: Deserializer<'de>,
119 {
120 deserializer.$deser_func($visitor::<V>)
121 }
122 }
123
124 struct $visitor<const V: $type>;
125
126 impl<'de, const V: $type> Visitor<'de> for $visitor<V> {
127 type Value = $struct<V>;
128 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
129 write!(formatter, "{V}")
130 }
131 fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E>
132 where
133 E: de::Error,
134 {
135 self.visit_i128(v as i128)
136 }
137 fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E>
138 where
139 E: de::Error,
140 {
141 self.visit_i128(v as i128)
142 }
143 fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
144 where
145 E: de::Error,
146 {
147 self.visit_i128(v as i128)
148 }
149 fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
150 where
151 E: de::Error,
152 {
153 self.visit_i128(v as i128)
154 }
155 fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
156 where
157 E: de::Error,
158 {
159 if v == V as i128 {
160 Ok($struct::<V>)
161 } else {
162 Err(E::invalid_value(Unexpected::Signed(V as i64), &self))
163 }
164 }
165 fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
166 where
167 E: de::Error,
168 {
169 self.visit_i128(v as i128)
170 }
171 fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>
172 where
173 E: de::Error,
174 {
175 self.visit_i128(v as i128)
176 }
177 fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
178 where
179 E: de::Error,
180 {
181 self.visit_i128(v as i128)
182 }
183 fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
184 where
185 E: de::Error,
186 {
187 self.visit_i128(v as i128)
188 }
189 fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
190 where
191 E: de::Error,
192 {
193 self.visit_i128(
194 i128::try_from(v)
195 .map_err(|_| E::invalid_value(Unexpected::Unsigned(v as u64), &Self))?,
196 )
197 }
198 }
199 )*
200 };
201}
202
203declare_int!(
204 i8 => ConstI8 ConstI8Visitor serialize_i8 deserialize_i8,
205 i16 => ConstI16 ConstI16Visitor serialize_i16 deserialize_i16,
206 i32 => ConstI32 ConstI32Visitor serialize_i32 deserialize_i32,
207 i64 => ConstI64 ConstI64Visitor serialize_i64 deserialize_i64,
208 i128 => ConstI128 ConstI128Visitor serialize_i128 deserialize_i128,
209);
210
211macro_rules! declare_uint {
212 ($($type:ty => $struct:ident $visitor:ident $ser_func:ident $deser_func:ident),* $(,)?) => {
213 $(
214 #[doc = concat!("A const `", stringify!($type), "`.")]
215 #[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Default)]
218 pub struct $struct<const V: $type>;
219
220 impl<const V: $type> Serialize for $struct<V> {
221 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
222 where
223 S: Serializer,
224 {
225 serializer.$ser_func(V)
226 }
227 }
228
229 impl<'de, const V: $type> Deserialize<'de> for $struct<V> {
230 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
231 where
232 D: Deserializer<'de>,
233 {
234 deserializer.$deser_func($visitor::<V>)
235 }
236 }
237
238 struct $visitor<const V: $type>;
239
240 impl<'de, const V: $type> Visitor<'de> for $visitor<V> {
241 type Value = $struct<V>;
242 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
243 write!(formatter, "{V}")
244 }
245 fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E>
246 where
247 E: de::Error,
248 {
249 self.visit_i128(v as i128)
250 }
251 fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E>
252 where
253 E: de::Error,
254 {
255 self.visit_i128(v as i128)
256 }
257 fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
258 where
259 E: de::Error,
260 {
261 self.visit_i128(v as i128)
262 }
263 fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
264 where
265 E: de::Error,
266 {
267 self.visit_i128(v as i128)
268 }
269 fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
270 where
271 E: de::Error,
272 {
273 if v < 0 {
274 Err(E::invalid_value(Unexpected::Signed(v as i64), &self))
275 } else {
276 self.visit_u128(v as u128)
277 }
278 }
279 fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
280 where
281 E: de::Error,
282 {
283 self.visit_u128(v as u128)
284 }
285 fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>
286 where
287 E: de::Error,
288 {
289 self.visit_u128(v as u128)
290 }
291 fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
292 where
293 E: de::Error,
294 {
295 self.visit_u128(v as u128)
296 }
297 fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
298 where
299 E: de::Error,
300 {
301 self.visit_u128(v as u128)
302 }
303 fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
304 where
305 E: de::Error,
306 {
307 if v == V as u128 {
308 Ok($struct::<V>)
309 } else {
310 Err(E::invalid_value(Unexpected::Unsigned(v as u64), &self))
311 }
312 }
313 }
314 )*
315 };
316}
317
318declare_uint!(
319 u8 => ConstU8 ConstU8Visitor serialize_u8 deserialize_u8,
320 u16 => ConstU16 ConstU16Visitor serialize_u16 deserialize_u16,
321 u32 => ConstU32 ConstU32Visitor serialize_u32 deserialize_u32,
322 u64 => ConstU64 ConstU64Visitor serialize_u64 deserialize_u64,
323 u128 => ConstU128 ConstU128Visitor serialize_u128 deserialize_u128,
324);
325
326#[derive(Debug, Copy, Clone, PartialEq, PartialOrd, Eq, Ord, Hash, Default)]
330pub struct ConstChar<const V: char>;
331
332impl<const V: char> Serialize for ConstChar<V> {
333 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
334 where
335 S: Serializer,
336 {
337 serializer.serialize_char(V)
338 }
339}
340
341impl<'de, const V: char> Deserialize<'de> for ConstChar<V> {
342 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
343 where
344 D: Deserializer<'de>,
345 {
346 deserializer.deserialize_char(ConstCharVisitor::<V>)
347 }
348}
349
350struct ConstCharVisitor<const V: char>;
351
352impl<'de, const V: char> Visitor<'de> for ConstCharVisitor<V> {
353 type Value = ConstChar<V>;
354 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
355 write!(formatter, "'{V}'")
356 }
357 fn visit_char<E>(self, v: char) -> Result<Self::Value, E>
358 where
359 E: de::Error,
360 {
361 if v == V {
362 Ok(ConstChar::<V>)
363 } else {
364 Err(E::invalid_value(Unexpected::Char(v), &self))
365 }
366 }
367 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
368 where
369 E: de::Error,
370 {
371 let mut chs = v.chars();
372 let ch = chs.next().ok_or_else(|| E::invalid_length(0, &self))?;
373 if chs.next().is_some() {
374 Err(E::invalid_length(2, &self))
375 } else {
376 self.visit_char(ch)
377 }
378 }
379}