use reqwest::Method;
use serde::{Deserialize, Serialize};
use crate::error::Result;
use crate::http::HttpClient;
use crate::models::Signer;
use crate::pagination::Page;
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct CreateSignerBody {
pub full_name: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub email: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub whatsapp_phone_number: Option<String>,
}
impl CreateSignerBody {
pub fn new<S: Into<String>>(full_name: S) -> Self {
CreateSignerBody {
full_name: full_name.into(),
email: None,
whatsapp_phone_number: None,
}
}
pub fn email<S: Into<String>>(mut self, email: S) -> Self {
self.email = Some(email.into());
self
}
pub fn whatsapp<S: Into<String>>(mut self, phone: S) -> Self {
self.whatsapp_phone_number = Some(phone.into());
self
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct UpdateSignerBody {
#[serde(skip_serializing_if = "Option::is_none")]
pub full_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub email: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub whatsapp_phone_number: Option<String>,
}
impl UpdateSignerBody {
pub fn new() -> Self {
Self::default()
}
pub fn full_name<S: Into<String>>(mut self, name: S) -> Self {
self.full_name = Some(name.into());
self
}
pub fn email<S: Into<String>>(mut self, email: S) -> Self {
self.email = Some(email.into());
self
}
pub fn whatsapp<S: Into<String>>(mut self, phone: S) -> Self {
self.whatsapp_phone_number = Some(phone.into());
self
}
}
#[derive(Debug)]
pub struct ListSignersRequest<'a> {
http: &'a HttpClient,
account_id: &'a str,
page: Option<u32>,
per_page: Option<u32>,
search: Option<String>,
sort: Option<String>,
}
impl<'a> ListSignersRequest<'a> {
pub fn page(mut self, page: u32) -> Self {
self.page = Some(page);
self
}
pub fn per_page(mut self, per_page: u32) -> Self {
self.per_page = Some(per_page);
self
}
pub fn search<S: Into<String>>(mut self, search: S) -> Self {
self.search = Some(search.into());
self
}
pub fn sort<S: Into<String>>(mut self, sort: S) -> Self {
self.sort = Some(sort.into());
self
}
pub async fn send(self) -> Result<Page<Signer>> {
let path = format!("accounts/{}/signers", self.account_id);
let mut req = self.http.request(Method::GET, &path)?;
let mut query: Vec<(&str, String)> = Vec::with_capacity(4);
if let Some(p) = self.page {
query.push(("page", p.to_string()));
}
if let Some(p) = self.per_page {
query.push(("per-page", p.to_string()));
}
if let Some(s) = self.search {
query.push(("search", s));
}
if let Some(s) = self.sort {
query.push(("sort", s));
}
if !query.is_empty() {
req = req.query(&query);
}
self.http.send_paged(req).await
}
}
#[derive(Debug)]
pub struct SignersApi<'a> {
http: &'a HttpClient,
account_id: String,
}
impl<'a> SignersApi<'a> {
pub(crate) fn new(http: &'a HttpClient, account_id: String) -> Self {
Self { http, account_id }
}
pub async fn create(&self, body: &CreateSignerBody) -> Result<Signer> {
let path = format!("accounts/{}/signers", self.account_id);
let req = self.http.request(Method::POST, &path)?.json(body);
self.http.send_envelope(req).await
}
pub fn list(&self) -> ListSignersRequest<'_> {
ListSignersRequest {
http: self.http,
account_id: &self.account_id,
page: None,
per_page: None,
search: None,
sort: None,
}
}
pub async fn get<S: AsRef<str>>(&self, signer_id: S) -> Result<Signer> {
let path = format!(
"accounts/{}/signers/{}",
self.account_id,
signer_id.as_ref()
);
let req = self.http.request(Method::GET, &path)?;
self.http.send_envelope(req).await
}
pub async fn update<S: AsRef<str>>(
&self,
signer_id: S,
body: &UpdateSignerBody,
) -> Result<Signer> {
let path = format!(
"accounts/{}/signers/{}",
self.account_id,
signer_id.as_ref()
);
let req = self.http.request(Method::PUT, &path)?.json(body);
self.http.send_envelope(req).await
}
pub async fn delete<S: AsRef<str>>(&self, signer_id: S) -> Result<()> {
let path = format!(
"accounts/{}/signers/{}",
self.account_id,
signer_id.as_ref()
);
let req = self.http.request(Method::DELETE, &path)?;
self.http.send_no_content(req).await
}
}