11use byteorder:: { ByteOrder , LittleEndian } ;
22
3+ use super :: decimal_tools:: { decode_money_bytes, decode_numeric_bytes} ;
34use crate :: decode:: Decode ;
45use crate :: encode:: { Encode , IsNull } ;
56use crate :: error:: BoxDynError ;
@@ -46,6 +47,9 @@ impl Type<Mssql> for f64 {
4647 | DataType :: DecimalN
4748 | DataType :: Numeric
4849 | DataType :: NumericN
50+ | DataType :: MoneyN
51+ | DataType :: Money
52+ | DataType :: SmallMoney
4953 )
5054 }
5155}
@@ -74,6 +78,13 @@ impl Decode<'_, Mssql> for f64 {
7478 DataType :: Numeric | DataType :: NumericN | DataType :: Decimal | DataType :: DecimalN => {
7579 decode_numeric ( value. as_bytes ( ) ?, precision, scale)
7680 }
81+ DataType :: MoneyN | DataType :: Money | DataType :: SmallMoney => {
82+ let numerator = decode_money_bytes ( value. as_bytes ( ) ?) ?;
83+ let denominator = 10_000 ;
84+ let integer_part = ( numerator / denominator) as f64 ;
85+ let fractional_part = ( numerator % denominator) as f64 / denominator as f64 ;
86+ Ok ( integer_part + fractional_part)
87+ }
7788 _ => Err ( err_protocol ! (
7889 "Decoding {:?} as a float failed because type {:?} is not implemented" ,
7990 value,
@@ -86,17 +97,16 @@ impl Decode<'_, Mssql> for f64 {
8697
8798#[ allow( clippy:: cast_precision_loss) ]
8899fn decode_numeric ( bytes : & [ u8 ] , _precision : u8 , mut scale : u8 ) -> Result < f64 , BoxDynError > {
89- let sign = if bytes[ 0 ] == 0 { -1. } else { 1. } ;
90- let rest = & bytes[ 1 ..] ;
91- let mut fixed_bytes = [ 0u8 ; 16 ] ;
92- fixed_bytes[ 0 ..rest. len ( ) ] . copy_from_slice ( rest) ;
93- let mut numerator = u128:: from_le_bytes ( fixed_bytes) ;
100+ let ( sign, mut numerator) = decode_numeric_bytes ( bytes) ?;
101+
94102 while numerator % 10 == 0 && scale > 0 {
95103 numerator /= 10 ;
96104 scale -= 1 ;
97105 }
98106 let denominator = 10u128 . pow ( scale as u32 ) ;
99107 let integer_part = ( numerator / denominator) as f64 ;
100108 let fractional_part = ( numerator % denominator) as f64 / denominator as f64 ;
101- Ok ( sign * ( integer_part + fractional_part) )
109+ let absolute = integer_part + fractional_part;
110+ let positive = sign == 1 ;
111+ Ok ( if positive { absolute } else { -absolute } )
102112}
0 commit comments