1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
use std::convert::TryInto; use byteorder::{ByteOrder, LittleEndian}; use crate::decode::Decode; use crate::encode::{Encode, IsNull}; use crate::error::BoxDynError; use crate::mysql::protocol::text::{ColumnFlags, ColumnType}; use crate::mysql::{MySql, MySqlTypeInfo, MySqlValueFormat, MySqlValueRef}; use crate::types::Type; fn int_compatible(ty: &MySqlTypeInfo) -> bool { matches!( ty.r#type, ColumnType::Tiny | ColumnType::Short | ColumnType::Long | ColumnType::Int24 | ColumnType::LongLong ) && !ty.flags.contains(ColumnFlags::UNSIGNED) } impl Type<MySql> for i8 { fn type_info() -> MySqlTypeInfo { MySqlTypeInfo::binary(ColumnType::Tiny) } fn compatible(ty: &MySqlTypeInfo) -> bool { int_compatible(ty) } } impl Type<MySql> for i16 { fn type_info() -> MySqlTypeInfo { MySqlTypeInfo::binary(ColumnType::Short) } fn compatible(ty: &MySqlTypeInfo) -> bool { int_compatible(ty) } } impl Type<MySql> for i32 { fn type_info() -> MySqlTypeInfo { MySqlTypeInfo::binary(ColumnType::Long) } fn compatible(ty: &MySqlTypeInfo) -> bool { int_compatible(ty) } } impl Type<MySql> for i64 { fn type_info() -> MySqlTypeInfo { MySqlTypeInfo::binary(ColumnType::LongLong) } fn compatible(ty: &MySqlTypeInfo) -> bool { int_compatible(ty) } } impl Encode<'_, MySql> for i8 { fn encode_by_ref(&self, buf: &mut Vec<u8>) -> IsNull { buf.extend(&self.to_le_bytes()); IsNull::No } } impl Encode<'_, MySql> for i16 { fn encode_by_ref(&self, buf: &mut Vec<u8>) -> IsNull { buf.extend(&self.to_le_bytes()); IsNull::No } } impl Encode<'_, MySql> for i32 { fn encode_by_ref(&self, buf: &mut Vec<u8>) -> IsNull { buf.extend(&self.to_le_bytes()); IsNull::No } } impl Encode<'_, MySql> for i64 { fn encode_by_ref(&self, buf: &mut Vec<u8>) -> IsNull { buf.extend(&self.to_le_bytes()); IsNull::No } } fn int_decode(value: MySqlValueRef<'_>) -> Result<i64, BoxDynError> { Ok(match value.format() { MySqlValueFormat::Text => value.as_str()?.parse()?, MySqlValueFormat::Binary => { let buf = value.as_bytes()?; LittleEndian::read_int(buf, buf.len()) } }) } impl Decode<'_, MySql> for i8 { fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> { int_decode(value)?.try_into().map_err(Into::into) } } impl Decode<'_, MySql> for i16 { fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> { int_decode(value)?.try_into().map_err(Into::into) } } impl Decode<'_, MySql> for i32 { fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> { int_decode(value)?.try_into().map_err(Into::into) } } impl Decode<'_, MySql> for i64 { fn decode(value: MySqlValueRef<'_>) -> Result<Self, BoxDynError> { int_decode(value) } }