use anyhow::Context; use lettre::{AsyncSendmailTransport, AsyncSmtpTransport, AsyncTransport, Message, Tokio1Executor}; use std::env; use url::Url; pub enum Mailer { Smtp(AsyncSmtpTransport), Sendmail(AsyncSendmailTransport), } impl Mailer { pub async fn send(&self, msg: Message) -> anyhow::Result<()> { match self { Mailer::Smtp(m) => { m.send(msg).await.context("SMTP send failed")?; Ok(()) } Mailer::Sendmail(m) => { m.send(msg).await.context("sendmail send failed")?; Ok(()) } } } } pub fn build_mailer_from_env() -> anyhow::Result { let raw = env::var("PDS_EMAIL_SMTP_URL") .context("PDS_EMAIL_SMTP_URL is not set in your pds.env file")?; let url = Url::parse(&raw).context("PDS_EMAIL_SMTP_URL is not a valid URL")?; let use_sendmail = url.scheme() == "sendmail" || url .query_pairs() .any(|(k, v)| k == "sendmail" && v == "true"); if use_sendmail { Ok(Mailer::Sendmail( AsyncSendmailTransport::::new(), )) } else { Ok(Mailer::Smtp( AsyncSmtpTransport::::from_url(raw.as_str())?.build(), )) } }