@@ -562,23 +562,32 @@ impl serde::Serialize for Decimal {
562562 }
563563}
564564
565- #[ cfg( feature = "serde-json" ) ]
565+ #[ cfg( all ( feature = "serde-json" , not ( feature = "serde-float" ) ) ) ]
566566impl From < Decimal > for serde_json:: Value {
567567 fn from ( decimal : Decimal ) -> serde_json:: Value {
568- # [ cfg ( all ( feature = "serde-float" , feature = "serde-arbitrary-precision" ) ) ]
569- {
570- return Value :: String ( d . to_string ( ) ) ;
571- }
568+ let value = crate :: str :: to_str_internal ( & decimal , true , None ) ;
569+ serde_json :: Value :: String ( value . 0 . to_string ( ) )
570+ }
571+ }
572572
573- #[ cfg( all( feature = "serde-float" , not( feature = "serde-arbitrary-precision" ) ) ) ]
574- {
575- return Value :: from ( d. as_f64 ( ) ) ;
576- }
573+ #[ cfg( all( feature = "serde-json" , feature = "serde-float" , not( feature = "serde-arbitrary-precision" ) ) ) ]
574+ impl From < Decimal > for serde_json:: Value {
575+ fn from ( decimal : Decimal ) -> serde_json:: Value {
576+ use num_traits:: ToPrimitive ;
577+ decimal
578+ . to_f64 ( )
579+ . and_then ( serde_json:: Number :: from_f64)
580+ . map ( serde_json:: Value :: Number )
581+ . unwrap_or ( serde_json:: Value :: Null )
582+ }
583+ }
577584
578- #[ cfg( not( feature = "serde-float" ) ) ]
579- {
580- return Value :: String ( d. to_string ( ) ) ;
581- }
585+ #[ cfg( all( feature = "serde-json" , feature = "serde-float" , feature = "serde-arbitrary-precision" ) ) ]
586+ impl From < Decimal > for serde_json:: Value {
587+ fn from ( decimal : Decimal ) -> serde_json:: Value {
588+ serde_json:: Number :: from_str ( & decimal. to_string ( ) )
589+ . map ( serde_json:: Value :: Number )
590+ . unwrap_or_else ( |_| serde_json:: Value :: String ( decimal. to_string ( ) ) )
582591 }
583592}
584593
@@ -977,4 +986,28 @@ mod test {
977986 assert_eq ! ( deserialized. value, original. value) ;
978987 assert ! ( deserialized. value. is_none( ) ) ;
979988 }
989+
990+ #[ test]
991+ #[ cfg( all( feature = "serde-json" , not( feature = "serde-float" ) ) ) ]
992+ fn into_value_matches_to_value_string ( ) {
993+ let d = Decimal :: from_str ( "1.234" ) . unwrap ( ) ;
994+ assert_eq ! ( serde_json:: Value :: from( d) , serde_json:: to_value( & d) . unwrap( ) ) ;
995+ assert_eq ! ( serde_json:: Value :: from( d) , serde_json:: Value :: String ( "1.234" . to_owned( ) ) ) ;
996+ }
997+
998+ #[ test]
999+ #[ cfg( all( feature = "serde-json" , feature = "serde-float" , not( feature = "serde-arbitrary-precision" ) ) ) ]
1000+ fn into_value_matches_to_value_float ( ) {
1001+ let d = Decimal :: from_str ( "1.5" ) . unwrap ( ) ;
1002+ assert_eq ! ( serde_json:: Value :: from( d) , serde_json:: to_value( & d) . unwrap( ) ) ;
1003+ }
1004+
1005+ #[ test]
1006+ #[ cfg( all( feature = "serde-json" , feature = "serde-float" , feature = "serde-arbitrary-precision" ) ) ]
1007+ fn into_value_matches_to_value_arbitrary_precision ( ) {
1008+ // 4.81 is unrepresentable as f64; arbitrary-precision must preserve it exactly.
1009+ let d = Decimal :: new ( 481 , 2 ) ;
1010+ assert_eq ! ( serde_json:: Value :: from( d) , serde_json:: to_value( & d) . unwrap( ) ) ;
1011+ assert_eq ! ( serde_json:: Value :: from( d) . to_string( ) , "4.81" ) ;
1012+ }
9801013}
0 commit comments