use std::collections::HashMap;
use reqwest::Method;
use serde::Serialize;
use serde_with::skip_serializing_none;
use crate::entities::{CreditBalance, Customer, CustomerPortalSession};
use crate::enums::Status;
use crate::ids::{CustomerID, SubscriptionID};
use crate::paginated::Paginated;
use crate::{Paddle, Result};
#[skip_serializing_none]
#[derive(Serialize)]
pub struct CustomersList<'a> {
#[serde(skip)]
client: &'a Paddle,
after: Option<CustomerID>,
#[serde(serialize_with = "crate::comma_separated")]
email: Option<Vec<String>>,
#[serde(serialize_with = "crate::comma_separated")]
id: Option<Vec<CustomerID>>,
order_by: Option<String>,
per_page: Option<usize>,
search: Option<String>,
status: Option<Status>,
}
impl<'a> CustomersList<'a> {
pub fn new(client: &'a Paddle) -> Self {
Self {
client,
after: None,
email: None,
id: None,
order_by: None,
per_page: None,
search: None,
status: None,
}
}
pub fn after(&mut self, customer_id: impl Into<CustomerID>) -> &mut Self {
self.after = Some(customer_id.into());
self
}
pub fn emails(&mut self, emails: impl IntoIterator<Item = impl AsRef<str>>) -> &mut Self {
self.email = Some(emails.into_iter().map(|s| s.as_ref().to_string()).collect());
self
}
pub fn ids(
&mut self,
customer_ids: impl IntoIterator<Item = impl Into<CustomerID>>,
) -> &mut Self {
self.id = Some(customer_ids.into_iter().map(Into::into).collect());
self
}
pub fn order_by_asc(&mut self, field: &str) -> &mut Self {
self.order_by = Some(format!("{}[ASC]", field));
self
}
pub fn order_by_desc(&mut self, field: &str) -> &mut Self {
self.order_by = Some(format!("{}[DESC]", field));
self
}
pub fn per_page(&mut self, entities_per_page: usize) -> &mut Self {
self.per_page = Some(entities_per_page);
self
}
pub fn search(&mut self, term: impl Into<String>) -> &mut Self {
self.search = Some(term.into());
self
}
pub fn status(&mut self, status: Status) -> &mut Self {
self.status = Some(status);
self
}
pub fn send(&self) -> Paginated<'_, Vec<Customer>> {
Paginated::new(self.client, "/customers", self)
}
}
#[skip_serializing_none]
#[derive(Serialize)]
pub struct CustomerCreate<'a> {
#[serde(skip)]
client: &'a Paddle,
email: String,
name: Option<String>,
custom_data: Option<HashMap<String, String>>,
locale: Option<String>,
}
impl<'a> CustomerCreate<'a> {
pub fn new(client: &'a Paddle, email: String) -> Self {
Self {
client,
email,
name: None,
custom_data: None,
locale: None,
}
}
pub fn name(&mut self, name: impl Into<String>) -> &mut Self {
self.name = Some(name.into());
self
}
pub fn custom_data(&mut self, custom_data: HashMap<String, String>) -> &mut Self {
self.custom_data = Some(custom_data);
self
}
pub fn locale(&mut self, locale: impl Into<String>) -> &mut Self {
self.locale = Some(locale.into());
self
}
pub async fn send(&self) -> Result<Customer> {
self.client.send(self, Method::POST, "/customers").await
}
}
#[derive(Serialize)]
pub struct CustomerGet<'a> {
#[serde(skip)]
client: &'a Paddle,
#[serde(skip)]
customer_id: CustomerID,
}
impl<'a> CustomerGet<'a> {
pub fn new(client: &'a Paddle, customer_id: impl Into<CustomerID>) -> Self {
Self {
client,
customer_id: customer_id.into(),
}
}
pub async fn send(&self) -> Result<Customer> {
self.client
.send(
self,
Method::GET,
&format!("/customers/{}", self.customer_id.as_ref()),
)
.await
}
}
#[skip_serializing_none]
#[derive(Serialize)]
pub struct CustomerUpdate<'a> {
#[serde(skip)]
client: &'a Paddle,
#[serde(skip)]
customer_id: CustomerID,
name: Option<String>,
email: Option<String>,
status: Option<Status>,
custom_data: Option<HashMap<String, String>>,
locale: Option<String>,
}
impl<'a> CustomerUpdate<'a> {
pub fn new(client: &'a Paddle, customer_id: impl Into<CustomerID>) -> Self {
Self {
client,
customer_id: customer_id.into(),
name: None,
email: None,
status: None,
custom_data: None,
locale: None,
}
}
pub fn name(&mut self, name: impl Into<String>) -> &mut Self {
self.name = Some(name.into());
self
}
pub fn email(&mut self, email: impl Into<String>) -> &mut Self {
self.email = Some(email.into());
self
}
pub fn status(&mut self, status: Status) -> &mut Self {
self.status = Some(status);
self
}
pub fn custom_data(&mut self, custom_data: HashMap<String, String>) -> &mut Self {
self.custom_data = Some(custom_data);
self
}
pub fn locale(&mut self, locale: impl Into<String>) -> &mut Self {
self.locale = Some(locale.into());
self
}
pub async fn send(&self) -> Result<Customer> {
self.client
.send(
self,
Method::PATCH,
&format!("/customers/{}", self.customer_id.as_ref()),
)
.await
}
}
#[skip_serializing_none]
#[derive(Serialize)]
pub struct CustomerCreditBalances<'a> {
#[serde(skip)]
client: &'a Paddle,
#[serde(skip)]
customer_id: CustomerID,
}
impl<'a> CustomerCreditBalances<'a> {
pub fn new(client: &'a Paddle, customer_id: impl Into<CustomerID>) -> Self {
Self {
client,
customer_id: customer_id.into(),
}
}
pub async fn send(&self) -> Result<Vec<CreditBalance>> {
self.client
.send(
self,
Method::GET,
&format!("/customers/{}/credit-balances", self.customer_id.as_ref()),
)
.await
}
}
#[skip_serializing_none]
#[derive(Serialize)]
pub struct PortalSessionCreate<'a> {
#[serde(skip)]
client: &'a Paddle,
#[serde(skip)]
customer_id: CustomerID,
subscription_ids: Option<Vec<SubscriptionID>>,
}
impl<'a> PortalSessionCreate<'a> {
pub fn new(client: &'a Paddle, customer_id: impl Into<CustomerID>) -> Self {
Self {
client,
customer_id: customer_id.into(),
subscription_ids: None,
}
}
pub fn subscription_ids(
&mut self,
subscription_ids: impl IntoIterator<Item = impl Into<SubscriptionID>>,
) -> &mut Self {
self.subscription_ids = Some(subscription_ids.into_iter().map(Into::into).collect());
self
}
pub async fn send(&self) -> Result<CustomerPortalSession> {
self.client
.send(
self,
Method::POST,
&format!("/customers/{}/portal-sessions", self.customer_id.as_ref()),
)
.await
}
}