1use crate::Error;
2use crate::Expected;
3use crate::Number;
4use crate::Unexpected;
5use serde::de;
6use serde::Deserialize;
7
8#[cfg(feature = "std")]
9impl<'de> serde::de::IntoDeserializer<'de, Error> for Number {
10 type Deserializer = crate::Deserializer<'de>;
11
12 fn into_deserializer(self) -> Self::Deserializer {
13 use crate::Deserializer;
14 use crate::Value;
15
16 Deserializer::new(Value::Number(self))
17 }
18}
19
20impl<'de> Deserialize<'de> for Number {
21 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
22 where
23 D: serde::Deserializer<'de>,
24 {
25 deserializer.deserialize_any(Visitor)
26 }
27}
28
29struct Visitor;
30
31impl de::Visitor<'_> for Visitor {
32 type Value = Number;
33
34 fn expecting(&self, formatter: &mut core::fmt::Formatter) -> core::fmt::Result {
35 formatter.write_str("a number")
36 }
37
38 fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E>
39 where
40 E: de::Error,
41 {
42 Ok(Number::I8(v))
43 }
44
45 fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E>
46 where
47 E: de::Error,
48 {
49 Ok(Number::I16(v))
50 }
51
52 fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
53 where
54 E: de::Error,
55 {
56 Ok(Number::I32(v))
57 }
58
59 fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
60 where
61 E: de::Error,
62 {
63 Ok(Number::I64(v))
64 }
65
66 fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
67 where
68 E: de::Error,
69 {
70 Ok(Number::I128(v))
71 }
72
73 fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
74 where
75 E: de::Error,
76 {
77 Ok(Number::U8(v))
78 }
79
80 fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>
81 where
82 E: de::Error,
83 {
84 Ok(Number::U16(v))
85 }
86
87 fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
88 where
89 E: de::Error,
90 {
91 Ok(Number::U32(v))
92 }
93
94 fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
95 where
96 E: de::Error,
97 {
98 Ok(Number::U64(v))
99 }
100
101 fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
102 where
103 E: de::Error,
104 {
105 Ok(Number::U128(v))
106 }
107
108 fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E>
109 where
110 E: de::Error,
111 {
112 Ok(Number::F32(v))
113 }
114
115 fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
116 where
117 E: de::Error,
118 {
119 Ok(Number::F64(v))
120 }
121}
122
123macro_rules! range {
124 ($min:ident, $max:ident as $dest:ty) => {
125 (($min::MIN as $dest)..=($max::MAX as $dest))
126 };
127 ($src:ident as $dest:ty) => {
128 (($src::MIN as $dest)..=($src::MAX as $dest))
129 };
130}
131
132macro_rules! coerce_int {
133 ($number:ident, $v:ident, $expected:ident, $visitor:ident) => {{
134 match $expected {
135 Expected::I8 => {
136 $visitor.visit_i8($v.try_into().map_err(|_| $number.unexpected($expected))?)
137 }
138 Expected::U8 => {
139 $visitor.visit_u8($v.try_into().map_err(|_| $number.unexpected($expected))?)
140 }
141 Expected::I16 => {
142 $visitor.visit_i16($v.try_into().map_err(|_| $number.unexpected($expected))?)
143 }
144 Expected::U16 => {
145 $visitor.visit_u16($v.try_into().map_err(|_| $number.unexpected($expected))?)
146 }
147 Expected::I32 => {
148 $visitor.visit_i32($v.try_into().map_err(|_| $number.unexpected($expected))?)
149 }
150 Expected::F32
151 if i32::try_from($v).is_ok()
152 && range!(i16, u16 as i32).contains(&i32::try_from($v).unwrap()) =>
153 {
154 $visitor.visit_f32($v as f32)
155 }
156 Expected::U32 => {
157 $visitor.visit_u32($v.try_into().map_err(|_| $number.unexpected($expected))?)
158 }
159 Expected::I64 => {
160 $visitor.visit_i64($v.try_into().map_err(|_| $number.unexpected($expected))?)
161 }
162 Expected::F64
163 if i64::try_from($v).is_ok()
164 && range!(i32, u32 as i64).contains(&i64::try_from($v).unwrap()) =>
165 {
166 $visitor.visit_f64($v as f64)
167 }
168 Expected::U64 => {
169 $visitor.visit_u64($v.try_into().map_err(|_| $number.unexpected($expected))?)
170 }
171 Expected::I128 => {
172 $visitor.visit_i128($v.try_into().map_err(|_| $number.unexpected($expected))?)
173 }
174 Expected::U128 => {
175 $visitor.visit_u128($v.try_into().map_err(|_| $number.unexpected($expected))?)
176 }
177 _ => Err($number.unexpected($expected)),
178 }
179 }};
180}
181
182enum NumberType {
183 Int,
184 F32,
185 F64,
186}
187
188impl Expected {
189 const fn number_type(&self) -> NumberType {
190 match self {
191 Expected::F32 => NumberType::F32,
192 Expected::F64 => NumberType::F64,
193 _ => NumberType::Int,
194 }
195 }
196}
197
198pub(super) fn visit<'de, V>(
199 number: Number,
200 expected: Expected,
201 coerce_numbers: bool,
202 visitor: V,
203) -> Result<V::Value, Error>
204where
205 V: de::Visitor<'de>,
206{
207 match (number, expected) {
208 (Number::I8(v), Expected::I8) => visitor.visit_i8(v),
209 (Number::U8(v), Expected::U8) => visitor.visit_u8(v),
210 (Number::I16(v), Expected::I16) => visitor.visit_i16(v),
211 (Number::U16(v), Expected::U16) => visitor.visit_u16(v),
212 (Number::I32(v), Expected::I32) => visitor.visit_i32(v),
213 (Number::U32(v), Expected::U32) => visitor.visit_u32(v),
214 (Number::F32(v), Expected::F32) => visitor.visit_f32(v),
215 (Number::I64(v), Expected::I64) => visitor.visit_i64(v),
216 (Number::U64(v), Expected::U64) => visitor.visit_u64(v),
217 (Number::F64(v), Expected::F64) => visitor.visit_f64(v),
218 (Number::I128(v), Expected::I128) => visitor.visit_i128(v),
219 (Number::U128(v), Expected::U128) => visitor.visit_u128(v),
220 (number, expected) => {
221 if !coerce_numbers {
222 return Err(number.unexpected(expected));
223 }
224
225 match (number, expected.number_type()) {
226 (Number::I8(v), _) => {
227 coerce_int!(number, v, expected, visitor)
228 }
229 (Number::U8(v), _) => {
230 coerce_int!(number, v, expected, visitor)
231 }
232 (Number::I16(v), _) => {
233 coerce_int!(number, v, expected, visitor)
234 }
235 (Number::U16(v), _) => {
236 coerce_int!(number, v, expected, visitor)
237 }
238 (Number::I32(v), _) => {
239 coerce_int!(number, v, expected, visitor)
240 }
241 (Number::U32(v), _) => {
242 coerce_int!(number, v, expected, visitor)
243 }
244 (Number::F32(v), NumberType::F64) => visitor.visit_f64(v as f64),
245 (Number::I64(v), _) => {
246 coerce_int!(number, v, expected, visitor)
247 }
248 (Number::U64(v), _) => {
249 coerce_int!(number, v, expected, visitor)
250 }
251 (Number::F64(v), NumberType::F32) if range!(f32 as f64).contains(&v) => {
252 visitor.visit_f32(v as f32)
253 }
254 (Number::I128(v), _) => {
255 coerce_int!(number, v, expected, visitor)
256 }
257 (Number::U128(v), _) => {
258 coerce_int!(number, v, expected, visitor)
259 }
260 _ => Err(number.unexpected(expected)),
261 }
262 }
263 }
264}