@@ -154,6 +154,164 @@ impl<'de> Deserializer<'de> {
154154 Err ( Error :: ExpectedString )
155155 }
156156 }
157+
158+ fn parse_integer_float ( & self ) -> Result < f64 > {
159+ let current = self . get_current ( ) ;
160+ if !current. is_float ( ) {
161+ return Err ( Error :: ExpectedFloat ) ;
162+ }
163+
164+ let value = current. to_float ( ) ?;
165+
166+ if !value. is_finite ( ) || value. fract ( ) != 0.0 {
167+ return Err ( Error :: ExpectedInteger ) ;
168+ }
169+
170+ Ok ( value)
171+ }
172+
173+ fn parse_signed_integer ( & self ) -> Result < i64 > {
174+ let current = self . get_current ( ) ;
175+
176+ if current. is_int ( ) {
177+ return Ok ( i64:: from ( current. to_int ( ) ?) ) ;
178+ }
179+
180+ if current. is_float ( ) {
181+ let value = self . parse_integer_float ( ) ?;
182+ if value < i64:: MIN as f64 || value > i64:: MAX as f64 {
183+ return Err ( crate :: ValueError :: OutOfRange . into ( ) ) ;
184+ }
185+ return Ok ( value as i64 ) ;
186+ }
187+
188+ #[ cfg( feature = "bigint" ) ]
189+ if current. is_bigint ( ) {
190+ return current. to_bigint ( ) ?. as_i64 ( ) . ok_or ( Error :: BigIntOverflow ) ;
191+ }
192+
193+ Err ( Error :: ExpectedInteger )
194+ }
195+
196+ fn parse_unsigned_integer ( & self ) -> Result < u64 > {
197+ let current = self . get_current ( ) ;
198+
199+ if current. is_int ( ) {
200+ let value = current. to_int ( ) ?;
201+ if value < 0 {
202+ return Err ( crate :: ValueError :: OutOfRange . into ( ) ) ;
203+ }
204+ return Ok ( value as u64 ) ;
205+ }
206+
207+ if current. is_float ( ) {
208+ let value = self . parse_integer_float ( ) ?;
209+ if value < 0.0 || value > u64:: MAX as f64 {
210+ return Err ( crate :: ValueError :: OutOfRange . into ( ) ) ;
211+ }
212+ return Ok ( value as u64 ) ;
213+ }
214+
215+ #[ cfg( feature = "bigint" ) ]
216+ if current. is_bigint ( ) {
217+ use num_traits:: ToPrimitive ;
218+
219+ return current
220+ . to_bigint ( ) ?
221+ . into_bigint ( )
222+ . to_u64 ( )
223+ . ok_or ( Error :: BigIntOverflow ) ;
224+ }
225+
226+ Err ( Error :: ExpectedInteger )
227+ }
228+
229+ #[ cfg( feature = "bigint" ) ]
230+ fn parse_signed_integer_128 ( & self ) -> Result < i128 > {
231+ let current = self . get_current ( ) ;
232+
233+ if current. is_bigint ( ) {
234+ use num_traits:: ToPrimitive ;
235+
236+ return current
237+ . to_bigint ( ) ?
238+ . into_bigint ( )
239+ . to_i128 ( )
240+ . ok_or ( Error :: BigIntOverflow ) ;
241+ }
242+
243+ if current. is_float ( ) {
244+ let value = self . parse_integer_float ( ) ?;
245+ if value < i128:: MIN as f64 || value > i128:: MAX as f64 {
246+ return Err ( crate :: ValueError :: OutOfRange . into ( ) ) ;
247+ }
248+ return Ok ( value as i128 ) ;
249+ }
250+
251+ self . parse_signed_integer ( ) . map ( i128:: from)
252+ }
253+
254+ #[ cfg( not( feature = "bigint" ) ) ]
255+ fn parse_signed_integer_128 ( & self ) -> Result < i128 > {
256+ if self . get_current ( ) . is_float ( ) {
257+ let value = self . parse_integer_float ( ) ?;
258+ if value < i128:: MIN as f64 || value > i128:: MAX as f64 {
259+ return Err ( crate :: ValueError :: OutOfRange . into ( ) ) ;
260+ }
261+ return Ok ( value as i128 ) ;
262+ }
263+
264+ self . parse_signed_integer ( ) . map ( i128:: from)
265+ }
266+
267+ #[ cfg( feature = "bigint" ) ]
268+ fn parse_unsigned_integer_128 ( & self ) -> Result < u128 > {
269+ let current = self . get_current ( ) ;
270+
271+ if current. is_bigint ( ) {
272+ use num_traits:: ToPrimitive ;
273+
274+ return current
275+ . to_bigint ( ) ?
276+ . into_bigint ( )
277+ . to_u128 ( )
278+ . ok_or ( Error :: BigIntOverflow ) ;
279+ }
280+
281+ if current. is_float ( ) {
282+ let value = self . parse_integer_float ( ) ?;
283+ if value < 0.0 || value > u128:: MAX as f64 {
284+ return Err ( crate :: ValueError :: OutOfRange . into ( ) ) ;
285+ }
286+ return Ok ( value as u128 ) ;
287+ }
288+
289+ self . parse_unsigned_integer ( ) . map ( u128:: from)
290+ }
291+
292+ #[ cfg( not( feature = "bigint" ) ) ]
293+ fn parse_unsigned_integer_128 ( & self ) -> Result < u128 > {
294+ if self . get_current ( ) . is_float ( ) {
295+ let value = self . parse_integer_float ( ) ?;
296+ if value < 0.0 || value > u128:: MAX as f64 {
297+ return Err ( crate :: ValueError :: OutOfRange . into ( ) ) ;
298+ }
299+ return Ok ( value as u128 ) ;
300+ }
301+
302+ self . parse_unsigned_integer ( ) . map ( u128:: from)
303+ }
304+ }
305+
306+ macro_rules! deserialize_integer {
307+ ( $name: ident, $visit: ident, $helper: ident) => {
308+ fn $name<V >( self , visitor: V ) -> std:: result:: Result <V :: Value , Self :: Error >
309+ where
310+ V : Visitor <' de>,
311+ {
312+ visitor. $visit( self . $helper( ) ?)
313+ }
314+ } ;
157315}
158316
159317impl < ' de , ' a > de:: Deserializer < ' de > for & ' a mut Deserializer < ' de > {
@@ -219,12 +377,23 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
219377
220378 forward_to_deserialize_any ! {
221379 bool
222- i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64
380+ f32 f64
223381 string char
224382 unit
225383 identifier ignored_any
226384 }
227385
386+ deserialize_integer ! ( deserialize_i8, visit_i64, parse_signed_integer) ;
387+ deserialize_integer ! ( deserialize_i16, visit_i64, parse_signed_integer) ;
388+ deserialize_integer ! ( deserialize_i32, visit_i64, parse_signed_integer) ;
389+ deserialize_integer ! ( deserialize_i64, visit_i64, parse_signed_integer) ;
390+ deserialize_integer ! ( deserialize_i128, visit_i128, parse_signed_integer_128) ;
391+ deserialize_integer ! ( deserialize_u8, visit_u64, parse_unsigned_integer) ;
392+ deserialize_integer ! ( deserialize_u16, visit_u64, parse_unsigned_integer) ;
393+ deserialize_integer ! ( deserialize_u32, visit_u64, parse_unsigned_integer) ;
394+ deserialize_integer ! ( deserialize_u64, visit_u64, parse_unsigned_integer) ;
395+ deserialize_integer ! ( deserialize_u128, visit_u128, parse_unsigned_integer_128) ;
396+
228397 fn deserialize_str < V > ( self , visitor : V ) -> std:: result:: Result < V :: Value , Self :: Error >
229398 where
230399 V : Visitor < ' de > ,
0 commit comments