use async_trait::async_trait;
use std::time::Duration;
use thiserror::Error;
#[derive(Debug, Clone)]
pub struct Message {
pub to: String,
pub from: String,
pub reply_to: Option<String>,
pub subject: String,
pub html: String,
pub text: String,
pub idempotency_key: Option<String>,
pub tags: Vec<String>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum SendOutcome {
Sent { id: String },
NotConfigured,
}
#[derive(Debug, Clone, Error)]
pub enum MailError {
#[error("mailer rejected the request as unauthorized (check the API key)")]
Unauthorized,
#[error("sending domain {domain:?} is not verified with the mailer")]
DomainNotVerified { domain: String },
#[error("mailer rejected the message as invalid: {detail}")]
Invalid { detail: String },
#[error("mailer rate limited the request; retry after {retry_after:?}")]
RateLimited { retry_after: Option<Duration> },
#[error("mailer upstream error: {0}")]
Upstream(String),
#[error("mailer transport error: {0}")]
Transport(String),
}
#[async_trait]
pub trait Mailer: Send + Sync {
async fn send(&self, message: Message) -> Result<SendOutcome, MailError>;
}