11use std:: any:: type_name;
22use std:: convert:: TryFrom ;
3- use std:: i16;
43
54use crate :: decode:: Decode ;
65use crate :: encode:: { Encode , IsNull } ;
@@ -27,10 +26,85 @@ impl Encode<'_, Mssql> for i8 {
2726 }
2827}
2928
29+ trait FromLeBytes < const N : usize > {
30+ fn from_le_bytes ( bytes : [ u8 ; N ] ) -> Self ;
31+ }
32+
33+ impl FromLeBytes < 1 > for i8 {
34+ fn from_le_bytes ( bytes : [ u8 ; 1 ] ) -> Self {
35+ i8:: from_le_bytes ( bytes)
36+ }
37+ }
38+
39+ impl FromLeBytes < 2 > for i16 {
40+ fn from_le_bytes ( bytes : [ u8 ; 2 ] ) -> Self {
41+ i16:: from_le_bytes ( bytes)
42+ }
43+ }
44+
45+ impl FromLeBytes < 4 > for i32 {
46+ fn from_le_bytes ( bytes : [ u8 ; 4 ] ) -> Self {
47+ i32:: from_le_bytes ( bytes)
48+ }
49+ }
50+
51+ impl FromLeBytes < 8 > for i64 {
52+ fn from_le_bytes ( bytes : [ u8 ; 8 ] ) -> Self {
53+ i64:: from_le_bytes ( bytes)
54+ }
55+ }
56+
57+ fn decode_int_direct < T , const N : usize > ( value : MssqlValueRef < ' _ > ) -> Result < T , BoxDynError >
58+ where
59+ T : FromLeBytes < N > + TryFrom < i64 > ,
60+ T :: Error : std:: error:: Error + Send + Sync + ' static ,
61+ {
62+ let ty = value. type_info . 0 . ty ;
63+ let precision = value. type_info . 0 . precision ;
64+ let scale = value. type_info . 0 . scale ;
65+
66+ match ty {
67+ DataType :: SmallInt
68+ | DataType :: Int
69+ | DataType :: TinyInt
70+ | DataType :: BigInt
71+ | DataType :: IntN => {
72+ let bytes_val = value. as_bytes ( ) ?;
73+ let len = bytes_val. len ( ) ;
74+
75+ if len > N {
76+ return Err ( err_protocol ! (
77+ "Decoding {:?} as {} failed because type {:?} has {} bytes, but can only handle {} bytes" ,
78+ value,
79+ type_name:: <T >( ) ,
80+ ty,
81+ len,
82+ N
83+ )
84+ . into ( ) ) ;
85+ }
86+
87+ let mut buf = [ 0u8 ; N ] ;
88+ buf[ ..len] . copy_from_slice ( bytes_val) ;
89+ Ok ( T :: from_le_bytes ( buf) )
90+ }
91+ DataType :: Numeric | DataType :: NumericN | DataType :: Decimal | DataType :: DecimalN => {
92+ let i64_val = decode_numeric ( value. as_bytes ( ) ?, precision, scale) ?;
93+ convert_integer :: < T > ( i64_val)
94+ }
95+ _ => Err ( err_protocol ! (
96+ "Decoding {:?} as {} failed because type {:?} is not supported" ,
97+ value,
98+ type_name:: <T >( ) ,
99+ ty
100+ )
101+ . into ( ) ) ,
102+ }
103+ }
104+
30105impl Decode < ' _ , Mssql > for i8 {
31106 fn decode ( value : MssqlValueRef < ' _ > ) -> Result < Self , BoxDynError > {
32- let i64_val = <i64 as Decode < Mssql > >:: decode ( value) ?;
33- convert_integer :: < Self > ( i64_val)
107+ decode_int_direct :: < Self , 1 > ( value)
34108 }
35109}
36110
@@ -57,8 +131,7 @@ impl Encode<'_, Mssql> for i16 {
57131
58132impl Decode < ' _ , Mssql > for i16 {
59133 fn decode ( value : MssqlValueRef < ' _ > ) -> Result < Self , BoxDynError > {
60- let i64_val = <i64 as Decode < Mssql > >:: decode ( value) ?;
61- convert_integer :: < Self > ( i64_val)
134+ decode_int_direct :: < Self , 2 > ( value)
62135 }
63136}
64137
@@ -82,8 +155,7 @@ impl Encode<'_, Mssql> for i32 {
82155
83156impl Decode < ' _ , Mssql > for i32 {
84157 fn decode ( value : MssqlValueRef < ' _ > ) -> Result < Self , BoxDynError > {
85- let i64_val = <i64 as Decode < Mssql > >:: decode ( value) ?;
86- convert_integer :: < Self > ( i64_val)
158+ decode_int_direct :: < Self , 4 > ( value)
87159 }
88160}
89161
@@ -118,43 +190,7 @@ impl Encode<'_, Mssql> for i64 {
118190
119191impl Decode < ' _ , Mssql > for i64 {
120192 fn decode ( value : MssqlValueRef < ' _ > ) -> Result < Self , BoxDynError > {
121- let ty = value. type_info . 0 . ty ;
122- let precision = value. type_info . 0 . precision ;
123- let scale = value. type_info . 0 . scale ;
124-
125- match ty {
126- DataType :: SmallInt
127- | DataType :: Int
128- | DataType :: TinyInt
129- | DataType :: BigInt
130- | DataType :: IntN => {
131- let mut buf = [ 0u8 ; 8 ] ;
132- let bytes_val = value. as_bytes ( ) ?;
133- let len = bytes_val. len ( ) ;
134-
135- if len > buf. len ( ) {
136- return Err ( err_protocol ! (
137- "Decoding {:?} as a i64 failed because type {:?} has more than {} bytes" ,
138- value,
139- ty,
140- buf. len( )
141- )
142- . into ( ) ) ;
143- }
144-
145- buf[ ..len] . copy_from_slice ( bytes_val) ;
146- Ok ( i64:: from_le_bytes ( buf) )
147- }
148- DataType :: Numeric | DataType :: NumericN | DataType :: Decimal | DataType :: DecimalN => {
149- decode_numeric ( value. as_bytes ( ) ?, precision, scale)
150- }
151- _ => Err ( err_protocol ! (
152- "Decoding {:?} as a i64 failed because type {:?} is not implemented" ,
153- value,
154- ty
155- )
156- . into ( ) ) ,
157- }
193+ decode_int_direct :: < Self , 8 > ( value)
158194 }
159195}
160196
0 commit comments