cdbc_mysql/types/
int.rs

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