use diesel::{ backend::Backend, deserialize::{self, FromSql, Queryable}, expression::AsExpression, serialize::ToSql, sql_types, }; use masking::Secret; use crate::{crypto::Encryptable, pii::EncryptionStrategy}; impl FromSql for Encryption where DB: Backend, Secret, EncryptionStrategy>: FromSql, { fn from_sql(bytes: DB::RawValue<'_>) -> deserialize::Result { , EncryptionStrategy>>::from_sql(bytes).map(Self::new) } } impl ToSql for Encryption where DB: Backend, Secret, EncryptionStrategy>: ToSql, { fn to_sql<'b>( &'b self, out: &mut diesel::serialize::Output<'b, '_, DB>, ) -> diesel::serialize::Result { self.get_inner().to_sql(out) } } impl Queryable for Encryption where DB: Backend, Secret, EncryptionStrategy>: FromSql, { type Row = Secret, EncryptionStrategy>; fn build(row: Self::Row) -> deserialize::Result { Ok(Self { inner: row }) } } #[derive(Debug, AsExpression, Clone, serde::Serialize, serde::Deserialize, Eq, PartialEq)] #[diesel(sql_type = sql_types::Binary)] #[repr(transparent)] pub struct Encryption { inner: Secret, EncryptionStrategy>, } impl From> for Encryption { fn from(value: Encryptable) -> Self { Self::new(value.into_encrypted()) } } impl Encryption { pub fn new(item: Secret, EncryptionStrategy>) -> Self { Self { inner: item } } #[inline] pub fn into_inner(self) -> Secret, EncryptionStrategy> { self.inner } #[inline] pub fn get_inner(&self) -> &Secret, EncryptionStrategy> { &self.inner } }