Skip to main content

sqlx_pg_ext_uint/
c_usize.rs

1use std::error::Error as StdError;
2
3use sqlx::{
4    Decode, Encode, Postgres, Type,
5    encode::IsNull,
6    postgres::{PgArgumentBuffer, PgHasArrayType, PgTypeInfo, PgValueRef},
7};
8
9const PG_EXT_TYPE: &str = "uint8";
10const PG_ARRAY_EXT_TYPE: &str = "uint8[]";
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
13pub struct USize {
14    value: usize,
15}
16
17impl From<usize> for USize {
18    fn from(value: usize) -> Self {
19        Self { value }
20    }
21}
22
23impl From<USize> for usize {
24    fn from(value: USize) -> Self {
25        value.value
26    }
27}
28
29impl USize {
30    pub fn get_type_size() -> usize {
31        std::mem::size_of::<usize>()
32    }
33}
34
35impl<'q> Encode<'q, Postgres> for USize {
36    fn encode_by_ref(
37        &self,
38        buf: &mut PgArgumentBuffer,
39    ) -> Result<IsNull, Box<dyn StdError + Send + Sync + 'static>> {
40        let bytes = self.value.to_be_bytes();
41        if bytes.len() != Self::get_type_size() {
42            return Err(format!(
43                "Invalid size for usize, data_len: {}, expected: {}",
44                bytes.len(),
45                Self::get_type_size()
46            )
47            .into());
48        }
49        <[u8; _] as Encode<Postgres>>::encode_by_ref(&bytes, buf)
50    }
51
52    fn size_hint(&self) -> usize {
53        Self::get_type_size()
54    }
55}
56
57impl<'r> Decode<'r, Postgres> for USize {
58    fn decode(value: PgValueRef<'r>) -> Result<Self, sqlx::error::BoxDynError> {
59        // 从大端字节序解析为usize
60        let bytes = <[u8; _] as Decode<Postgres>>::decode(value)?;
61        if bytes.len() != Self::get_type_size() {
62            return Err(format!(
63                "Invalid size for usize, data_len: {}, expected: {}",
64                bytes.len(),
65                Self::get_type_size()
66            )
67            .into());
68        }
69        Ok(usize::from_be_bytes(bytes).into())
70    }
71}
72
73impl Type<Postgres> for USize {
74    fn type_info() -> PgTypeInfo {
75        PgTypeInfo::with_name(PG_EXT_TYPE)
76    }
77}
78
79impl PgHasArrayType for USize {
80    fn array_type_info() -> PgTypeInfo {
81        PgTypeInfo::with_name(PG_ARRAY_EXT_TYPE)
82    }
83}