use std::error::Error;
use lettre::transport::smtp::{response::Response, authentication::Credentials};
use lettre::{Message, AsyncSmtpTransport, AsyncTransport, Tokio1Executor};
use lettre::message::{Mailbox, MessageBuilder};
use crate::web::{Result, WebErrorKind};
use crate::server::Settings;
pub struct Email<'a> {
mailer: &'a Option<Mailer>,
message: Message,
}
impl<'a> Email<'a> {
pub fn builder(mailer: &'a Option<Mailer>) -> EmailBuilder<'a> {
EmailBuilder {mailer, builder: Message::builder()}
}
pub async fn send(self) -> Result<EmailResponse> {
if let Some(mailer) = self.mailer {
Ok(EmailResponse {0: mailer.0.send(self.message).await?})
} else {
Err(WebErrorKind::BadEmail.to_box())
}
}
}
#[derive(Debug, Clone)]
pub struct Mailer(AsyncSmtpTransport<Tokio1Executor>);
impl Mailer {
pub fn new(settings: &Settings) -> Result<Self> {
if let Some(smtp_username) = settings.get("smtp_username") {
if let Some(smtp_username) = smtp_username.as_str() {
if let Some(smtp_password) = settings.get("smtp_password") {
if let Some(smtp_host) = settings.get("smtp_relay") {
if let Some(smtp_host) = smtp_host.as_str() {
if !smtp_username.is_empty() && !smtp_host.is_empty() {
let creds = Credentials::new(smtp_username.to_string(), smtp_password.to_string());
let mailer = AsyncSmtpTransport::<Tokio1Executor>::relay(smtp_host)?
.credentials(creds)
.build();
return Ok(Self {0: mailer});
}
}
}
}
}
}
Err(WebErrorKind::BadMailer.to_box())
}
}
pub struct EmailAddress(Mailbox);
pub struct EmailBuilder<'a> {
mailer: &'a Option<Mailer>,
builder: MessageBuilder,
}
impl<'a> EmailBuilder<'a> {
pub fn to(self, address: EmailAddress) -> Self {
Self {mailer: self.mailer, builder: self.builder.to(address.0)}
}
pub fn subject<S: Into<String>>(self, subject: S) -> Self {
Self {mailer: self.mailer, builder: self.builder.subject(subject)}
}
pub fn body(self, body: String) -> Result<Email<'a>> {
match self.builder.body(body) {
Ok(message) => Ok(Email {mailer: self.mailer, message}),
Err(e) => Err(Box::new(e) as Box<dyn Error + Send + Sync>),
}
}
}
pub struct EmailResponse(Response);