use async_trait::async_trait;
use lettre::{AsyncTransport, address::Envelope};
pub struct CealTransport<T>(T);
impl<T: AsyncTransport> CealTransport<T> {
pub const fn new(transport: T) -> Self {
Self(transport)
}
}
#[async_trait]
impl<T: AsyncTransport + Send + Sync> AsyncTransport for CealTransport<T> {
type Ok = T::Ok;
type Error = T::Error;
async fn send_raw(
&self,
envelope: &Envelope,
email: &[u8]
) -> Result<Self::Ok, Self::Error> {
let email = crate::encrypt(email, envelope.to()).await;
self.0.send_raw(envelope, &email).await
}
async fn shutdown(&self) {
self.0.shutdown().await
}
}
pub trait AsyncTransportExt: AsyncTransport + Sized {
fn with_opportunistic_encryption(self) -> CealTransport<Self>;
}
impl<T: AsyncTransport> AsyncTransportExt for T {
fn with_opportunistic_encryption(self) -> CealTransport<Self> {
CealTransport::new(self)
}
}