julid-rs 1.6.1803398874989

A crate and loadable extension for SQLite that provides Joe's ULIDs.
Documentation
use std::borrow::Cow;

use sqlx::{
    encode::IsNull,
    sqlite::{SqliteArgumentValue, SqliteValueRef},
    Decode, Encode, Sqlite, Value, ValueRef,
};

use crate::Julid;

impl sqlx::Type<sqlx::Sqlite> for Julid {
    fn type_info() -> <sqlx::Sqlite as sqlx::Database>::TypeInfo {
        <&[u8] as sqlx::Type<sqlx::Sqlite>>::type_info()
    }
}

impl<'q> Encode<'q, Sqlite> for Julid {
    fn encode_by_ref(
        &self,
        args: &mut Vec<SqliteArgumentValue<'q>>,
    ) -> std::result::Result<
        sqlx::encode::IsNull,
        std::boxed::Box<(dyn std::error::Error + std::marker::Send + std::marker::Sync + 'static)>,
    > {
        args.push(SqliteArgumentValue::Blob(Cow::Owned(
            self.as_bytes().to_vec(),
        )));
        Ok(IsNull::No)
    }
}

impl Decode<'_, Sqlite> for Julid {
    fn decode(value: SqliteValueRef<'_>) -> Result<Self, sqlx::error::BoxDynError> {
        let julid = match <&[u8] as Decode<Sqlite>>::decode(value.to_owned().as_ref()) {
            Ok(bytes) => {
                let bytes: [u8; 16] = bytes.try_into().unwrap_or_default();
                Julid::from_bytes(bytes)
            }
            _ => {
                let string = <&str as Decode<Sqlite>>::decode(value)?;
                Julid::from_str(string)?
            }
        };

        Ok(julid)
    }
}