sqlx_xugu/types/
uint.rs

1use crate::arguments::XuguArgumentValue;
2use crate::error::BoxDynError;
3use crate::protocol::text::{ColumnFlags, ColumnType};
4use crate::{Xugu, XuguTypeInfo, XuguValueRef};
5use byteorder::{BigEndian, ByteOrder};
6use sqlx_core::decode::Decode;
7use sqlx_core::encode::{Encode, IsNull};
8use sqlx_core::types::Type;
9use std::borrow::Cow;
10
11fn uint_compatible(ty: &XuguTypeInfo) -> bool {
12    matches!(
13        ty.r#type,
14        ColumnType::TINYINT
15            | ColumnType::SMALLINT
16            | ColumnType::INTEGER
17            | ColumnType::BIGINT
18            | ColumnType::BOOLEAN
19    ) && !ty.flags.contains(ColumnFlags::IS_LOB)
20}
21
22impl Type<Xugu> for u8 {
23    fn type_info() -> XuguTypeInfo {
24        XuguTypeInfo::binary(ColumnType::TINYINT)
25    }
26
27    fn compatible(ty: &XuguTypeInfo) -> bool {
28        uint_compatible(ty)
29    }
30}
31
32impl Type<Xugu> for u16 {
33    fn type_info() -> XuguTypeInfo {
34        XuguTypeInfo::binary(ColumnType::SMALLINT)
35    }
36
37    fn compatible(ty: &XuguTypeInfo) -> bool {
38        uint_compatible(ty)
39    }
40}
41
42impl Type<Xugu> for u32 {
43    fn type_info() -> XuguTypeInfo {
44        XuguTypeInfo::binary(ColumnType::INTEGER)
45    }
46
47    fn compatible(ty: &XuguTypeInfo) -> bool {
48        uint_compatible(ty)
49    }
50}
51
52impl Type<Xugu> for u64 {
53    fn type_info() -> XuguTypeInfo {
54        XuguTypeInfo::binary(ColumnType::BIGINT)
55    }
56
57    fn compatible(ty: &XuguTypeInfo) -> bool {
58        uint_compatible(ty)
59    }
60}
61
62impl Encode<'_, Xugu> for u8 {
63    fn encode_by_ref(&self, args: &mut Vec<XuguArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
64        let buf = self.to_be_bytes().to_vec();
65        args.push(XuguArgumentValue::Bin(Cow::Owned(buf)));
66
67        Ok(IsNull::No)
68    }
69}
70
71impl Encode<'_, Xugu> for u16 {
72    fn encode_by_ref(&self, args: &mut Vec<XuguArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
73        let buf = self.to_be_bytes().to_vec();
74        args.push(XuguArgumentValue::Bin(Cow::Owned(buf)));
75
76        Ok(IsNull::No)
77    }
78}
79
80impl Encode<'_, Xugu> for u32 {
81    fn encode_by_ref(&self, args: &mut Vec<XuguArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
82        let buf = self.to_be_bytes().to_vec();
83        args.push(XuguArgumentValue::Bin(Cow::Owned(buf)));
84
85        Ok(IsNull::No)
86    }
87}
88
89impl Encode<'_, Xugu> for u64 {
90    fn encode_by_ref(&self, args: &mut Vec<XuguArgumentValue<'_>>) -> Result<IsNull, BoxDynError> {
91        let buf = self.to_be_bytes().to_vec();
92        args.push(XuguArgumentValue::Bin(Cow::Owned(buf)));
93
94        Ok(IsNull::No)
95    }
96}
97
98fn uint_decode(value: XuguValueRef<'_>) -> Result<u64, BoxDynError> {
99    let buf = value.as_bytes()?;
100
101    // Check conditions that could cause `read_int()` to panic.
102    if buf.is_empty() {
103        return Err("empty buffer".into());
104    }
105
106    if buf.len() > 8 {
107        return Err(format!(
108            "expected no more than 8 bytes for integer value, got {}",
109            buf.len()
110        )
111        .into());
112    }
113
114    if value.type_info.r#type == ColumnType::BOOLEAN {
115        return <bool as Decode<Xugu>>::decode(value).map(|x| x as u64);
116    }
117
118    Ok(BigEndian::read_uint(buf, buf.len()))
119}
120
121impl Decode<'_, Xugu> for u8 {
122    fn decode(value: XuguValueRef<'_>) -> Result<Self, BoxDynError> {
123        uint_decode(value)?.try_into().map_err(Into::into)
124    }
125}
126
127impl Decode<'_, Xugu> for u16 {
128    fn decode(value: XuguValueRef<'_>) -> Result<Self, BoxDynError> {
129        uint_decode(value)?.try_into().map_err(Into::into)
130    }
131}
132
133impl Decode<'_, Xugu> for u32 {
134    fn decode(value: XuguValueRef<'_>) -> Result<Self, BoxDynError> {
135        uint_decode(value)?.try_into().map_err(Into::into)
136    }
137}
138
139impl Decode<'_, Xugu> for u64 {
140    fn decode(value: XuguValueRef<'_>) -> Result<Self, BoxDynError> {
141        uint_decode(value)
142    }
143}