paystack/
utils.rs

1use serde::de::Error;
2use std::fmt::Formatter;
3use std::str::FromStr;
4
5pub fn string_or_number_to_u8<'de, D>(deserializer: D) -> Result<u8, D::Error>
6where
7    D: serde::Deserializer<'de>,
8{
9    struct StringOrNumberVisitor;
10
11    impl<'de> serde::de::Visitor<'de> for StringOrNumberVisitor {
12        type Value = u8;
13
14        fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
15            formatter.write_str("a string or an integer")
16        }
17
18        fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
19        where
20            E: Error,
21        {
22            u8::from_str(v).map_err(serde::de::Error::custom)
23        }
24
25        fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
26        where
27            E: Error,
28        {
29            if v <= u8::MAX as u64 {
30                Ok(v as u8)
31            } else {
32                Err(E::custom(format!("u64 value {} is out of range for u8", v)))
33            }
34        }
35    }
36
37    deserializer.deserialize_any(StringOrNumberVisitor)
38}
39
40pub fn string_or_number_to_u16<'de, D>(deserializer: D) -> Result<u16, D::Error>
41where
42    D: serde::Deserializer<'de>,
43{
44    struct StringOrNumberVisitor;
45
46    impl<'de> serde::de::Visitor<'de> for StringOrNumberVisitor {
47        type Value = u16;
48
49        fn expecting(&self, formatter: &mut Formatter) -> std::fmt::Result {
50            formatter.write_str("a string or an integer")
51        }
52
53        fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
54        where
55            E: Error,
56        {
57            u16::from_str(v).map_err(serde::de::Error::custom)
58        }
59
60        fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
61        where
62            E: Error,
63        {
64            if v <= u16::MAX as u64 {
65                Ok(v as u16)
66            } else {
67                Err(E::custom(format!(
68                    "u64 value {} is out of range for u16",
69                    v
70                )))
71            }
72        }
73    }
74
75    deserializer.deserialize_any(StringOrNumberVisitor)
76}
77
78pub fn option_string_or_number_to_u8<'de, D>(deserializer: D) -> Result<Option<u8>, D::Error>
79where
80    D: serde::Deserializer<'de>,
81{
82    struct OptionStringOrNumberVisitor;
83
84    impl<'de> serde::de::Visitor<'de> for OptionStringOrNumberVisitor {
85        type Value = Option<u8>;
86
87        fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
88            formatter.write_str("an optional u8, either as a number, a string, or null")
89        }
90
91        fn visit_none<E>(self) -> Result<Self::Value, E>
92        where
93            E: Error,
94        {
95            Ok(None)
96        }
97
98        fn visit_unit<E>(self) -> Result<Self::Value, E>
99        where
100            E: Error,
101        {
102            Ok(None)
103        }
104
105        fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
106        where
107            D: serde::Deserializer<'de>,
108        {
109            // Delegate to the exisiting deserializer
110            super::string_or_number_to_u8(deserializer).map(Some)
111        }
112    }
113
114    deserializer.deserialize_option(OptionStringOrNumberVisitor)
115}
116
117pub fn option_string_or_number_to_u16<'de, D>(deserializer: D) -> Result<Option<u16>, D::Error>
118where
119    D: serde::Deserializer<'de>,
120{
121    struct OptionStringOrNumberVisitor;
122
123    impl<'de> serde::de::Visitor<'de> for OptionStringOrNumberVisitor {
124        type Value = Option<u16>;
125
126        fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
127            formatter.write_str("an optional u8, either as a number, a string, or null")
128        }
129
130        fn visit_none<E>(self) -> Result<Self::Value, E>
131        where
132            E: Error,
133        {
134            Ok(None)
135        }
136
137        fn visit_unit<E>(self) -> Result<Self::Value, E>
138        where
139            E: Error,
140        {
141            Ok(None)
142        }
143
144        fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
145        where
146            D: serde::Deserializer<'de>,
147        {
148            // Delegate to the exisiting deserializer
149            super::string_or_number_to_u16(deserializer).map(Some)
150        }
151    }
152
153    deserializer.deserialize_option(OptionStringOrNumberVisitor)
154}