1
1
use byteorder:: { ByteOrder , LittleEndian } ;
2
2
3
+ use super :: decimal_tools:: { decode_money_bytes, decode_numeric_bytes} ;
3
4
use crate :: decode:: Decode ;
4
5
use crate :: encode:: { Encode , IsNull } ;
5
6
use crate :: error:: BoxDynError ;
@@ -46,6 +47,9 @@ impl Type<Mssql> for f64 {
46
47
| DataType :: DecimalN
47
48
| DataType :: Numeric
48
49
| DataType :: NumericN
50
+ | DataType :: MoneyN
51
+ | DataType :: Money
52
+ | DataType :: SmallMoney
49
53
)
50
54
}
51
55
}
@@ -74,6 +78,13 @@ impl Decode<'_, Mssql> for f64 {
74
78
DataType :: Numeric | DataType :: NumericN | DataType :: Decimal | DataType :: DecimalN => {
75
79
decode_numeric ( value. as_bytes ( ) ?, precision, scale)
76
80
}
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
+ }
77
88
_ => Err ( err_protocol ! (
78
89
"Decoding {:?} as a float failed because type {:?} is not implemented" ,
79
90
value,
@@ -86,17 +97,16 @@ impl Decode<'_, Mssql> for f64 {
86
97
87
98
#[ allow( clippy:: cast_precision_loss) ]
88
99
fn 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
+
94
102
while numerator % 10 == 0 && scale > 0 {
95
103
numerator /= 10 ;
96
104
scale -= 1 ;
97
105
}
98
106
let denominator = 10u128 . pow ( scale as u32 ) ;
99
107
let integer_part = ( numerator / denominator) as f64 ;
100
108
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 } )
102
112
}
0 commit comments