@@ -4,6 +4,8 @@ use core::{fmt, str};
4
4
5
5
use serde:: de:: { self , Visitor } ;
6
6
7
+ use lexical_core:: { try_atof32_lossy_slice, ErrorCode } ;
8
+
7
9
use self :: enum_:: UnitVariantAccess ;
8
10
use self :: map:: MapAccess ;
9
11
use self :: seq:: SeqAccess ;
@@ -27,6 +29,9 @@ pub enum Error {
27
29
/// EOF while parsing a string.
28
30
EofWhileParsingString ,
29
31
32
+ /// EOF while parsing a JSON number.
33
+ EofWhileParsingNumber ,
34
+
30
35
/// EOF while parsing a JSON value.
31
36
EofWhileParsingValue ,
32
37
@@ -360,11 +365,20 @@ impl<'a, 'de> de::Deserializer<'de> for &'a mut Deserializer<'de> {
360
365
deserialize_unsigned ! ( self , visitor, u64 , visit_u64)
361
366
}
362
367
363
- fn deserialize_f32 < V > ( self , _visitor : V ) -> Result < V :: Value >
368
+ fn deserialize_f32 < V > ( self , visitor : V ) -> Result < V :: Value >
364
369
where
365
370
V : Visitor < ' de > ,
366
371
{
367
- unreachable ! ( )
372
+ self . parse_whitespace ( ) . ok_or ( Error :: EofWhileParsingValue ) ?;
373
+ let r = try_atof32_lossy_slice ( & self . slice [ self . index ..] ) ;
374
+ match r. error . code {
375
+ ErrorCode :: Success | ErrorCode :: InvalidDigit => {
376
+ self . index += r. error . index ;
377
+ visitor. visit_f32 ( r. value )
378
+ } ,
379
+ ErrorCode :: Empty => Err ( Error :: EofWhileParsingNumber ) ,
380
+ _ => Err ( Error :: InvalidNumber )
381
+ }
368
382
}
369
383
370
384
fn deserialize_f64 < V > ( self , _visitor : V ) -> Result < V :: Value >
@@ -711,6 +725,46 @@ mod tests {
711
725
assert ! ( crate :: from_str:: <Temperature >( r#"{ "temperature": -129 }"# ) . is_err( ) ) ;
712
726
}
713
727
728
+ #[ test]
729
+ fn struct_f32 ( ) {
730
+ #[ derive( Debug , Deserialize , PartialEq ) ]
731
+ struct Temperature {
732
+ temperature : f32 ,
733
+ }
734
+
735
+ assert_eq ! (
736
+ crate :: from_str( r#"{ "temperature": -17.2 }"# ) ,
737
+ Ok ( Temperature { temperature: -17.2 } )
738
+ ) ;
739
+
740
+ assert_eq ! (
741
+ crate :: from_str( r#"{ "temperature": -0.0 }"# ) ,
742
+ Ok ( Temperature { temperature: -0. } )
743
+ ) ;
744
+
745
+ assert_eq ! (
746
+ crate :: from_str( r#"{ "temperature": -2.1e-3 }"# ) ,
747
+ Ok ( Temperature { temperature: -2.1e-3 } )
748
+ ) ;
749
+
750
+ assert_eq ! (
751
+ crate :: from_str( r#"{ "temperature": -3 }"# ) ,
752
+ Ok ( Temperature { temperature: -3. } )
753
+ ) ;
754
+
755
+ use core:: f32;
756
+
757
+ assert_eq ! (
758
+ crate :: from_str( r#"{ "temperature": -1e500 }"# ) ,
759
+ Ok ( Temperature { temperature: f32 :: NEG_INFINITY } )
760
+ ) ;
761
+
762
+ assert ! ( crate :: from_str:: <Temperature >( r#"{ "temperature": 1e1e1 }"# ) . is_err( ) ) ;
763
+ assert ! ( crate :: from_str:: <Temperature >( r#"{ "temperature": -2-2 }"# ) . is_err( ) ) ;
764
+ assert ! ( crate :: from_str:: <Temperature >( r#"{ "temperature": 1 1 }"# ) . is_err( ) ) ;
765
+ assert ! ( crate :: from_str:: <Temperature >( r#"{ "temperature": 0.0. }"# ) . is_err( ) ) ;
766
+ }
767
+
714
768
#[ test]
715
769
fn struct_option ( ) {
716
770
#[ derive( Debug , Deserialize , PartialEq ) ]
0 commit comments