Skip to content

Commit 241a890

Browse files
committed
refactor mssql signed int decoding
1 parent 01c120f commit 241a890

File tree

1 file changed

+52
-64
lines changed
  • sqlx-core/src/mssql/types

1 file changed

+52
-64
lines changed

sqlx-core/src/mssql/types/int.rs

+52-64
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ impl Encode<'_, Mssql> for i8 {
2828

2929
impl Decode<'_, Mssql> for i8 {
3030
fn decode(value: MssqlValueRef<'_>) -> Result<Self, BoxDynError> {
31-
decode_integer(value)
31+
let i64_val = <i64 as Decode<Mssql>>::decode(value)?;
32+
convert_integer::<Self>(i64_val)
3233
}
3334
}
3435

@@ -55,7 +56,8 @@ impl Encode<'_, Mssql> for i16 {
5556

5657
impl Decode<'_, Mssql> for i16 {
5758
fn decode(value: MssqlValueRef<'_>) -> Result<Self, BoxDynError> {
58-
decode_integer(value)
59+
let i64_val = <i64 as Decode<Mssql>>::decode(value)?;
60+
convert_integer::<Self>(i64_val)
5961
}
6062
}
6163

@@ -79,7 +81,8 @@ impl Encode<'_, Mssql> for i32 {
7981

8082
impl Decode<'_, Mssql> for i32 {
8183
fn decode(value: MssqlValueRef<'_>) -> Result<Self, BoxDynError> {
82-
decode_integer(value)
84+
let i64_val = <i64 as Decode<Mssql>>::decode(value)?;
85+
convert_integer::<Self>(i64_val)
8386
}
8487
}
8588

@@ -114,7 +117,43 @@ impl Encode<'_, Mssql> for i64 {
114117

115118
impl Decode<'_, Mssql> for i64 {
116119
fn decode(value: MssqlValueRef<'_>) -> Result<Self, BoxDynError> {
117-
decode_integer(value)
120+
let ty = value.type_info.0.ty;
121+
let precision = value.type_info.0.precision;
122+
let scale = value.type_info.0.scale;
123+
124+
match ty {
125+
DataType::SmallInt
126+
| DataType::Int
127+
| DataType::TinyInt
128+
| DataType::BigInt
129+
| DataType::IntN => {
130+
let mut buf = [0u8; 8];
131+
let bytes_val = value.as_bytes()?;
132+
let len = bytes_val.len();
133+
134+
if len > buf.len() {
135+
return Err(err_protocol!(
136+
"Decoding {:?} as a i64 failed because type {:?} has more than {} bytes",
137+
value,
138+
ty,
139+
buf.len()
140+
)
141+
.into());
142+
}
143+
144+
buf[..len].copy_from_slice(&bytes_val);
145+
Ok(i64::from_le_bytes(buf))
146+
}
147+
DataType::Numeric | DataType::NumericN | DataType::Decimal | DataType::DecimalN => {
148+
decode_numeric(value.as_bytes()?, precision, scale)
149+
}
150+
_ => Err(err_protocol!(
151+
"Decoding {:?} as a i64 failed because type {:?} is not implemented",
152+
value,
153+
ty
154+
)
155+
.into()),
156+
}
118157
}
119158
}
120159

@@ -132,69 +171,18 @@ fn decode_numeric(bytes: &[u8], _precision: u8, mut scale: u8) -> Result<i64, Bo
132171
Ok(n * if negative { -1 } else { 1 })
133172
}
134173

135-
fn decode_integer<T>(value: MssqlValueRef<'_>) -> Result<T, BoxDynError>
174+
fn convert_integer<T>(i64_val: i64) -> Result<T, BoxDynError>
136175
where
137176
T: TryFrom<i64>,
138177
T::Error: std::error::Error + Send + Sync + 'static,
139178
{
140-
let ty = value.type_info.0.ty;
141-
let precision = value.type_info.0.precision;
142-
let scale = value.type_info.0.scale;
143-
144-
let type_name = type_name::<T>();
145-
146-
match ty {
147-
DataType::SmallInt
148-
| DataType::Int
149-
| DataType::TinyInt
150-
| DataType::BigInt
151-
| DataType::IntN => {
152-
let mut buf = [0u8; 8];
153-
let bytes_val = value.as_bytes()?;
154-
let len = bytes_val.len();
155-
156-
if len > buf.len() {
157-
return Err(err_protocol!(
158-
"Decoding {:?} as a {} failed because type {:?} has more than {} bytes",
159-
value,
160-
type_name,
161-
ty,
162-
buf.len()
163-
)
164-
.into());
165-
}
166-
167-
buf[..len].copy_from_slice(&bytes_val);
168-
169-
let i64_val = i64::from_le_bytes(buf);
170-
T::try_from(i64_val).map_err(|_| {
171-
err_protocol!(
172-
"Decoding {:?} as a {} failed because value {} is out of range",
173-
value,
174-
type_name,
175-
i64_val
176-
)
177-
.into()
178-
})
179-
}
180-
DataType::Numeric | DataType::NumericN | DataType::Decimal | DataType::DecimalN => {
181-
let n = decode_numeric(value.as_bytes()?, precision, scale)?;
182-
T::try_from(n).map_err(|_| {
183-
err_protocol!(
184-
"Decoding {:?} as a {} failed because value {} is out of range",
185-
value,
186-
type_name,
187-
n
188-
)
189-
.into()
190-
})
191-
}
192-
_ => Err(err_protocol!(
193-
"Decoding {:?} as a {} failed because type {:?} is not implemented",
194-
value,
195-
type_name,
196-
ty
179+
T::try_from(i64_val).map_err(|err| {
180+
err_protocol!(
181+
"Converting {} to {} failed: {}",
182+
i64_val,
183+
type_name::<T>(),
184+
err
197185
)
198-
.into()),
199-
}
186+
.into()
187+
})
200188
}

0 commit comments

Comments
 (0)