sqlx_pg_ext_uint/
c_u64.rs

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