use reqwest::Method;
use serde::Deserialize;
use serde_json::Value;
use super::{query, urlencode};
use crate::error::Result;
use crate::http::HttpTransport;
use crate::models::{
BatchResponse, Email, EmailDetail, EmailEvent, EmailSearchHit, IdStatus, ScheduledEmail,
SendEmail, SendEmailResponse, ValidationResult,
};
#[derive(Debug, Clone)]
pub struct Emails {
http: HttpTransport,
}
#[derive(Deserialize)]
struct SavedSearches {
searches: Vec<Value>,
}
impl Emails {
pub(crate) fn new(http: HttpTransport) -> Self {
Self { http }
}
pub async fn send(&self, message: &SendEmail) -> Result<SendEmailResponse> {
self.http
.request_json(Method::POST, "/v1/emails/", message)
.await
}
pub async fn send_batch(&self, messages: &[SendEmail]) -> Result<BatchResponse> {
self.http
.request_json(Method::POST, "/v1/emails/batch", &messages)
.await
}
pub async fn validate(&self, message: &SendEmail) -> Result<ValidationResult> {
self.http
.request_json(Method::POST, "/v1/emails/validate", message)
.await
}
pub async fn list(
&self,
status: Option<&str>,
page: Option<u64>,
limit: Option<u64>,
) -> Result<Vec<Email>> {
let q = query(&[
("status", status.map(String::from)),
("page", page.map(|p| p.to_string())),
("limit", limit.map(|l| l.to_string())),
]);
self.http
.request(Method::GET, &format!("/v1/emails/{q}"))
.await
}
pub async fn get(&self, id: &str) -> Result<EmailDetail> {
self.http
.request(Method::GET, &format!("/v1/emails/{}", urlencode(id)))
.await
}
pub async fn events(&self, id: &str) -> Result<Vec<EmailEvent>> {
self.http
.request(
Method::GET,
&format!("/v1/emails/{}/events", urlencode(id)),
)
.await
}
pub async fn retry(&self, id: &str) -> Result<SendEmailResponse> {
self.http
.request(Method::POST, &format!("/v1/emails/{}/retry", urlencode(id)))
.await
}
pub async fn search(
&self,
q: Option<&str>,
status: Option<&str>,
tag: Option<&str>,
page: Option<u64>,
limit: Option<u64>,
) -> Result<Vec<EmailSearchHit>> {
let qs = query(&[
("q", q.map(String::from)),
("status", status.map(String::from)),
("tag", tag.map(String::from)),
("page", page.map(|p| p.to_string())),
("limit", limit.map(|l| l.to_string())),
]);
self.http
.request(Method::GET, &format!("/v1/emails/search{qs}"))
.await
}
pub async fn list_scheduled(&self) -> Result<Vec<ScheduledEmail>> {
self.http
.request(Method::GET, "/v1/emails/scheduled")
.await
}
pub async fn cancel_scheduled(&self, id: &str) -> Result<IdStatus> {
self.http
.request(
Method::DELETE,
&format!("/v1/emails/scheduled/{}", urlencode(id)),
)
.await
}
pub async fn send_scheduled_now(&self, id: &str) -> Result<IdStatus> {
self.http
.request(
Method::POST,
&format!("/v1/emails/scheduled/{}/send-now", urlencode(id)),
)
.await
}
pub async fn updates(&self, since: &str) -> Result<Vec<Email>> {
let q = query(&[("since", Some(since.to_string()))]);
self.http
.request(Method::GET, &format!("/v1/emails/updates{q}"))
.await
}
pub async fn get_saved_searches(&self) -> Result<Vec<Value>> {
let r: SavedSearches = self
.http
.request(Method::GET, "/v1/emails/saved-searches")
.await?;
Ok(r.searches)
}
pub async fn set_saved_searches(&self, searches: Vec<Value>) -> Result<Vec<Value>> {
let body = serde_json::json!({ "searches": searches });
let r: SavedSearches = self
.http
.request_json(Method::PUT, "/v1/emails/saved-searches", &body)
.await?;
Ok(r.searches)
}
}