inline-postgres-impl 0.1.0

Implementation of the inline-postgres crate - do not use on its own
Documentation
use tokio_postgres::types::{FromSql, ToSql, self, to_sql_checked, IsNull};
use ulid::Ulid;
use bytes::{Buf, BufMut};

/// A type that is suitable for keys in the database.
/// 
/// Internally it uses an [`Ulid`].
/// It is randomly generated and contains 80 bits of entropy.
/// The first 48 bits encode a timestamp such that the keys are ordered by time of insertion
/// 
/// Chance of collision is negligible - `4e-7` if a billion keys are generated in the same millisecond.
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Key(pub(crate) Ulid);

impl Key {
    pub fn new() -> Self {
        Self(Ulid::new())
    }
    pub(crate) fn accepts_impl(ty: &types::Type) -> bool {
       matches!(ty, &types::Type::UUID)
    }
}

impl FromSql<'_> for Key {
    fn from_sql(_ty: &types::Type, mut raw: &[u8]) -> Result<Self, Box<dyn std::error::Error + Sync + Send>> {
        let mut bytes = [0u8; 16];
        for b in bytes.iter_mut() {
            *b = raw.get_u8();
        }
        Ok(Key(Ulid(u128::from_be_bytes(bytes))))
    }

    fn accepts(ty: &types::Type) -> bool {
        Key::accepts_impl(ty)
    }
}

impl ToSql for Key {
    fn to_sql(&self, _ty: &types::Type, out: &mut types::private::BytesMut) -> Result<types::IsNull, Box<dyn std::error::Error + Sync + Send>>
    where
        Self: Sized {
            let bytes = self.0.0.to_be_bytes();
            for b in bytes.into_iter() {
                out.put_u8(b);
            }
            Ok(IsNull::No)
    }

    fn accepts(ty: &types::Type) -> bool
    where
        Self: Sized {
        Key::accepts_impl(ty)
    }

    to_sql_checked!();
}