11use crate :: serde:: encode:: { Encode , Encoded } ;
22use bigdecimal:: {
33 num_bigint:: { BigInt , Sign } ,
4- BigDecimal , Signed , Zero ,
4+ BigDecimal , Signed , Zero , num_traits :: ToBytes ,
55} ;
66
77const EXPONENT_BIAS : i64 = 101 ;
@@ -30,7 +30,7 @@ impl TryFrom<f32> for Decimal32 {
3030 }
3131}
3232
33- #[ derive( thiserror:: Error , Debug ) ]
33+ #[ derive( thiserror:: Error , Debug , PartialEq ) ]
3434pub enum Decimal32ConversionError {
3535 #[ error( "Failed to parse f32 value to Decimal32 value." ) ]
3636 ParseDecimal32Error ( #[ from] bigdecimal:: ParseBigDecimalError ) ,
@@ -59,25 +59,8 @@ fn encode_to_bytes(value: &BigDecimal) -> Result<Vec<u8>, Decimal32ConversionErr
5959
6060
6161 let ( mut coeff, mut exp) = value. as_bigint_and_exponent ( ) ;
62- verify_coefficient_not_too_large ( & coeff) ?;
63- verify_exponent_below_max ( & exp) ?;
64- let sign_bit = match coeff. sign ( ) {
65- Sign :: Minus => 0x80 ,
66- _ => 0 ,
67- } ;
68-
69- let biased_exp = ( exp + EXPONENT_BIAS ) as u8 ;
70- let coeff_bytes = coeff. abs ( ) . to_bytes_be ( ) . 1 ;
71-
72- verify_coefficient_scaling ( & coeff_bytes) ?;
73-
74- let mut result: [ u8 ; 4 ] = [ sign_bit | biased_exp, 0 , 0 , 0 ] ;
75- let offset = 4 - coeff_bytes. len ( ) ;
76- for ( i, & byte) in coeff_bytes. iter ( ) . enumerate ( ) {
77- result[ offset + i] = byte;
78- }
7962
80- Ok ( result. to_vec ( ) )
63+ Ok ( result. to_be_bytes ( ) . to_vec ( ) )
8164}
8265
8366fn set_sign_bit ( mut result : u32 , sign : Sign ) -> Result < u32 , ConversionError > {
@@ -94,37 +77,19 @@ fn set_sign_bit(mut result: u32, sign: Sign) -> Result<u32, ConversionError> {
9477 }
9578}
9679
97- fn verify_coefficient_not_too_large ( coeff : & BigInt ) -> Result < ( ) , ConversionError > {
98- if coeff. abs ( ) > COEFFICIENT_MAX . into ( ) {
99- return Err ( Decimal32ConversionError :: CoefficientTooLarge ) ;
100- }
101- Ok ( ( ) )
102- }
103-
104- fn verify_exponent_below_max ( exp : & i64 ) -> Result < ( ) , Decimal32ConversionError > {
105- if exp > & EXPONENT_MAX {
106- return Err ( Decimal32ConversionError :: ExponentOverflow ) ;
107- }
108- Ok ( ( ) )
109- }
110-
111- fn verify_no_exponent_underflow ( exp : & i64 ) -> Result < ( ) , Decimal32ConversionError > {
112- if exp < & EXPONENT_MIN {
113- return Err ( Decimal32ConversionError :: ExponentUnderflow ) ;
80+ fn set_exponent_bits ( mut result : u32 , exp : i64 ) -> Result < u32 , ConversionError > {
81+ match exp {
82+ _ if exp < EXPONENT_MIN => Err ( Decimal32ConversionError :: ExponentUnderflow ) ,
83+ _ if exp > EXPONENT_MAX => Err ( Decimal32ConversionError :: ExponentOverflow ) ,
84+ x => {
85+ Ok ( result)
86+ }
11487 }
115- Ok ( ( ) )
11688}
11789
118- fn verify_coefficient_scaling ( coeff_bytes : & Vec < u8 > ) -> Result < ( ) , Decimal32ConversionError > {
119- if coeff_bytes. len ( ) > 3 {
120- return Err ( Decimal32ConversionError :: CoefficientScalingFailedError ) ;
121- }
122- Ok ( ( ) )
123- }
12490
12591#[ cfg( test) ]
12692mod test {
127- use bigdecimal:: num_traits:: ToBytes ;
12893
12994 use super :: * ;
13095
@@ -148,4 +113,37 @@ mod test {
148113 fn set_sign_bit_resturns_error_on_non_zero_base_number ( ) {
149114 assert ! ( set_sign_bit( 4 , Sign :: Minus ) . is_err( ) ) ;
150115 }
116+
117+ #[ test]
118+ fn set_exponent_bits_if_exponent_too_large_returns_err ( ) {
119+ assert_eq ! ( set_exponent_bits( 0x80000000 , 100 ) , Err ( Decimal32ConversionError :: ExponentOverflow ) ) ;
120+ assert_eq ! ( set_exponent_bits( 0x80000000 , 97 ) , Err ( Decimal32ConversionError :: ExponentOverflow ) ) ;
121+ }
122+
123+ #[ test]
124+ fn set_exponent_bits_if_exponent_too_small_returns_err ( ) {
125+ assert_eq ! ( set_exponent_bits( 0x80000000 , -100 ) , Err ( Decimal32ConversionError :: ExponentUnderflow ) ) ;
126+ assert_eq ! ( set_exponent_bits( 0x80000000 , -96 ) , Err ( Decimal32ConversionError :: ExponentUnderflow ) ) ;
127+ }
128+
129+ #[ test]
130+ fn set_exponent_bits_works ( ) {
131+ assert_eq ! ( set_exponent_bits( 0x80000000 , 1 ) . unwrap( ) , 0x86600000 ) ;
132+ assert_eq ! ( set_exponent_bits( 0x80000000 , 2 ) . unwrap( ) , 0x86700000 ) ;
133+ assert_eq ! ( set_exponent_bits( 0x80000000 , 8 ) . unwrap( ) , 0x86D00000 ) ;
134+ assert_eq ! ( set_exponent_bits( 0x80000000 , 16 ) . unwrap( ) , 0x87500000 ) ;
135+ assert_eq ! ( set_exponent_bits( 0x80000000 , 32 ) . unwrap( ) , 0x88500000 ) ;
136+ assert_eq ! ( set_exponent_bits( 0x80000000 , 64 ) . unwrap( ) , 0x8A500000 ) ;
137+ assert_eq ! ( set_exponent_bits( 0x80000000 , 96 ) . unwrap( ) , 0x8C500000 ) ;
138+ assert_eq ! ( set_exponent_bits( 0x80000000 , 0 ) . unwrap( ) , 0x86500000 ) ;
139+ assert_eq ! ( set_exponent_bits( 0x80000000 , -1 ) . unwrap( ) , 0x86400000 ) ;
140+ // TODO continue here
141+ assert_eq ! ( set_exponent_bits( 0x80000000 , -2 ) . unwrap( ) , 0x86600000 ) ;
142+ assert_eq ! ( set_exponent_bits( 0x80000000 , -8 ) . unwrap( ) , 0x86600000 ) ;
143+ assert_eq ! ( set_exponent_bits( 0x80000000 , -16 ) . unwrap( ) , 0x86600000 ) ;
144+ assert_eq ! ( set_exponent_bits( 0x80000000 , -32 ) . unwrap( ) , 0x86600000 ) ;
145+ assert_eq ! ( set_exponent_bits( 0x80000000 , -64 ) . unwrap( ) , 0x86600000 ) ;
146+ assert_eq ! ( set_exponent_bits( 0x80000000 , -95 ) . unwrap( ) , 0x86600000 ) ;
147+ }
148+
151149}
0 commit comments