mirror of
https://github.com/launchbadge/sqlx.git
synced 2025-12-29 21:00:54 +00:00
feat(mysql): impl Type for i8, i16, i32, i64, i128, and isize
This commit is contained in:
parent
01d4255137
commit
4c1d2fa679
@ -122,15 +122,13 @@
|
||||
|
||||
mod bool;
|
||||
mod bytes;
|
||||
mod int;
|
||||
mod str;
|
||||
mod uint;
|
||||
|
||||
// TODO: mod decimal;
|
||||
// TODO: mod int;
|
||||
// TODO: mod float;
|
||||
// TODO: mod time;
|
||||
// TODO: mod str;
|
||||
// TODO: mod bytes;
|
||||
// TODO: mod bit;
|
||||
// TODO: mod uuid;
|
||||
// TODO: mod json;
|
||||
|
||||
104
sqlx-mysql/src/types/int.rs
Normal file
104
sqlx-mysql/src/types/int.rs
Normal file
@ -0,0 +1,104 @@
|
||||
use sqlx_core::{decode, encode};
|
||||
use sqlx_core::{Decode, Encode, Type};
|
||||
|
||||
use super::uint::decode_int_or_uint;
|
||||
use crate::type_info::MySqlTypeInfo;
|
||||
use crate::{MySql, MySqlOutput, MySqlRawValue, MySqlTypeId};
|
||||
|
||||
// check that the incoming value is not too large or too small
|
||||
// to fit into the target SQL type
|
||||
fn ensure_not_too_large_or_too_small(value: i128, ty: &MySqlTypeInfo) -> encode::Result<()> {
|
||||
let max: i128 = match ty.id() {
|
||||
MySqlTypeId::TINYINT => i8::MAX as _,
|
||||
MySqlTypeId::SMALLINT => i16::MAX as _,
|
||||
MySqlTypeId::MEDIUMINT => 0x7F_FF_FF as _,
|
||||
MySqlTypeId::INT => i32::MAX as _,
|
||||
MySqlTypeId::BIGINT => i64::MAX as _,
|
||||
|
||||
MySqlTypeId::TINYINT_UNSIGNED => u8::MAX as _,
|
||||
MySqlTypeId::SMALLINT_UNSIGNED => u16::MAX as _,
|
||||
MySqlTypeId::MEDIUMINT_UNSIGNED => 0xFF_FF_FF as _,
|
||||
MySqlTypeId::INT_UNSIGNED => u32::MAX as _,
|
||||
MySqlTypeId::BIGINT_UNSIGNED => u64::MAX as _,
|
||||
|
||||
// not an integer type
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let min: i128 = match ty.id() {
|
||||
MySqlTypeId::TINYINT => i8::MIN as _,
|
||||
MySqlTypeId::SMALLINT => i16::MIN as _,
|
||||
MySqlTypeId::MEDIUMINT => 0x80_00_00 as _,
|
||||
MySqlTypeId::INT => i32::MIN as _,
|
||||
MySqlTypeId::BIGINT => i64::MIN as _,
|
||||
|
||||
MySqlTypeId::TINYINT_UNSIGNED => u8::MIN as _,
|
||||
MySqlTypeId::SMALLINT_UNSIGNED => u16::MIN as _,
|
||||
MySqlTypeId::MEDIUMINT_UNSIGNED => 0 as _,
|
||||
MySqlTypeId::INT_UNSIGNED => u32::MIN as _,
|
||||
MySqlTypeId::BIGINT_UNSIGNED => u64::MIN as _,
|
||||
|
||||
// not an integer type
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
if value > max {
|
||||
return Err(encode::Error::msg(format!(
|
||||
"number `{}` too large to fit in SQL type `{}`",
|
||||
value,
|
||||
ty.name()
|
||||
)));
|
||||
}
|
||||
|
||||
if value < min {
|
||||
return Err(encode::Error::msg(format!(
|
||||
"number `{}` too small to fit in SQL type `{}`",
|
||||
value,
|
||||
ty.name()
|
||||
)));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
macro_rules! impl_type_int {
|
||||
($ty:ty $(: $real:ty)? => $sql:ident) => {
|
||||
impl Type<MySql> for $ty {
|
||||
fn type_id() -> MySqlTypeId {
|
||||
MySqlTypeId::$sql
|
||||
}
|
||||
|
||||
fn compatible(ty: &MySqlTypeInfo) -> bool {
|
||||
ty.id().is_integer()
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode<MySql> for $ty {
|
||||
fn encode(&self, ty: &MySqlTypeInfo, out: &mut MySqlOutput<'_>) -> encode::Result<()> {
|
||||
ensure_not_too_large_or_too_small((*self $(as $real)?).into(), ty)?;
|
||||
|
||||
out.buffer().extend_from_slice(&self.to_le_bytes());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r> Decode<'r, MySql> for $ty {
|
||||
fn decode(value: MySqlRawValue<'r>) -> decode::Result<Self> {
|
||||
decode_int_or_uint(&value)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_type_int! { i8 => TINYINT }
|
||||
impl_type_int! { i16 => SMALLINT }
|
||||
impl_type_int! { i32 => INT }
|
||||
impl_type_int! { i64 => BIGINT }
|
||||
impl_type_int! { i128 => BIGINT }
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
impl_type_int! { isize: i64 => BIGINT }
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
impl_type_int! { isize: i32 => INT }
|
||||
Loading…
x
Reference in New Issue
Block a user