use crate::audiences::AudiencesApi;
use crate::contacts::ContactsApi;
use crate::domains::DomainsApi;
use crate::emails::EmailsApi;
use crate::error::UnosendError;
use reqwest::Client;
use serde::de::DeserializeOwned;
use serde::Serialize;
const DEFAULT_BASE_URL: &str = "https://api.unosend.co/v1";
#[derive(Clone)]
pub struct Unosend {
api_key: String,
base_url: String,
http_client: Client,
}
impl Unosend {
pub fn new(api_key: impl Into<String>) -> Self {
Self::with_base_url(api_key, DEFAULT_BASE_URL)
}
pub fn with_base_url(api_key: impl Into<String>, base_url: impl Into<String>) -> Self {
Self {
api_key: api_key.into(),
base_url: base_url.into(),
http_client: Client::new(),
}
}
pub fn emails(&self) -> EmailsApi {
EmailsApi::new(self.clone())
}
pub fn domains(&self) -> DomainsApi {
DomainsApi::new(self.clone())
}
pub fn audiences(&self) -> AudiencesApi {
AudiencesApi::new(self.clone())
}
pub fn contacts(&self) -> ContactsApi {
ContactsApi::new(self.clone())
}
pub(crate) async fn post<T, R>(&self, path: &str, body: &T) -> Result<R, UnosendError>
where
T: Serialize,
R: DeserializeOwned,
{
let url = format!("{}{}", self.base_url, path);
let response = self
.http_client
.post(&url)
.header("Authorization", format!("Bearer {}", self.api_key))
.header("Content-Type", "application/json")
.header("User-Agent", "unosend-rust/1.0.0")
.json(body)
.send()
.await?;
self.handle_response(response).await
}
pub(crate) async fn get<R>(&self, path: &str) -> Result<R, UnosendError>
where
R: DeserializeOwned,
{
let url = format!("{}{}", self.base_url, path);
let response = self
.http_client
.get(&url)
.header("Authorization", format!("Bearer {}", self.api_key))
.header("User-Agent", "unosend-rust/1.0.0")
.send()
.await?;
self.handle_response(response).await
}
pub(crate) async fn delete(&self, path: &str) -> Result<(), UnosendError> {
let url = format!("{}{}", self.base_url, path);
let response = self
.http_client
.delete(&url)
.header("Authorization", format!("Bearer {}", self.api_key))
.header("User-Agent", "unosend-rust/1.0.0")
.send()
.await?;
if !response.status().is_success() {
let status = response.status().as_u16();
let text = response.text().await.unwrap_or_default();
return Err(UnosendError::Api {
message: text,
status_code: status,
});
}
Ok(())
}
async fn handle_response<R>(&self, response: reqwest::Response) -> Result<R, UnosendError>
where
R: DeserializeOwned,
{
let status = response.status();
let text = response.text().await?;
if !status.is_success() {
return Err(UnosendError::Api {
message: text,
status_code: status.as_u16(),
});
}
serde_json::from_str(&text).map_err(|e| UnosendError::Parse(e.to_string()))
}
}