@@ -5,10 +5,7 @@ use core::{
55 str:: FromStr ,
66} ;
77
8- use crate :: {
9- error:: { ParseIntError , ParseIntErrorKind , TryFromIntError } ,
10- MAX_SAFE_INT ,
11- } ;
8+ use crate :: { error:: { ParseIntError , ParseIntErrorKind , TryFromIntError } , MAX_SAFE_INT } ;
129#[ cfg( feature = "serde" ) ]
1310use serde:: {
1411 de:: { Error as _, Unexpected } ,
@@ -414,6 +411,39 @@ impl UInt {
414411 Self :: new_saturating ( self . 0 . saturating_pow ( exp) )
415412 }
416413
414+ /// Deserialization function for use with `#[serde(deserialize_with = ...)]` that performs
415+ /// deserialization through `f64` instead of `u64`.
416+ /// This allows deserializing from numbers with a fractional component like `.0`.
417+ ///
418+ /// # Example
419+ /// ```rs
420+ /// use serde::Deserialize;
421+ /// use js_int::UInt;
422+ ///
423+ /// #[derive(Deserialize)]
424+ /// struct Point {
425+ /// #[serde(deserialize_with = "UInt::deserialize_via_float")]
426+ /// x: UInt;
427+ /// #[serde(deserialize_with = "UInt::deserialize_via_float")]
428+ /// y: UInt;
429+ /// }
430+ /// ```
431+ #[ cfg( feature = "serde" ) ]
432+ pub fn deserialize_via_float < ' de , D > ( deserializer : D ) -> Result < Self , D :: Error >
433+ where
434+ D : Deserializer < ' de > ,
435+ {
436+ const EXPECTING : & str = "a number between 0 and 2^53 - 1 without fractional component" ;
437+
438+ let val = f64:: deserialize ( deserializer) ?;
439+
440+ if val < 0.0 || val > MAX_SAFE_UINT as f64 || !super :: is_acceptable_float ( val) {
441+ Err ( D :: Error :: invalid_value ( Unexpected :: Float ( val) , & EXPECTING ) )
442+ } else {
443+ Ok ( Self ( val as u64 ) )
444+ }
445+ }
446+
417447 // TODO: wrapping_* methods, overflowing_* methods
418448}
419449
@@ -571,30 +601,14 @@ impl<'de> Deserialize<'de> for UInt {
571601 where
572602 D : Deserializer < ' de > ,
573603 {
574- #[ cfg( not( feature = "float_deserialize" ) ) ]
575- {
576- let val = u64:: deserialize ( deserializer) ?;
577-
578- Self :: new ( val) . ok_or_else ( || {
579- D :: Error :: invalid_value (
580- Unexpected :: Unsigned ( val) ,
581- & "an integer between 0 and 2^53 - 1" ,
582- )
583- } )
584- }
585-
586- #[ cfg( feature = "float_deserialize" ) ]
587- {
588- const EXPECTING : & str = "a number between 0 and 2^53 - 1 without fractional component" ;
589-
590- let val = f64:: deserialize ( deserializer) ?;
591-
592- if val < 0.0 || val > MAX_SAFE_UINT as f64 || !super :: is_acceptable_float ( val) {
593- Err ( D :: Error :: invalid_value ( Unexpected :: Float ( val) , & EXPECTING ) )
594- } else {
595- Ok ( Self ( val as u64 ) )
596- }
597- }
604+ let val = u64:: deserialize ( deserializer) ?;
605+
606+ Self :: new ( val) . ok_or_else ( || {
607+ D :: Error :: invalid_value (
608+ Unexpected :: Unsigned ( val) ,
609+ & "an integer between 0 and 2^53 - 1" ,
610+ )
611+ } )
598612 }
599613}
600614
0 commit comments