use std::fmt;
use reqwest::Method;
use serde::{Deserialize, Serialize};
use strum_macros::{AsRefStr, Display, EnumIter, EnumString};
use crate::{Client, TwilioError};
pub struct Accounts<'a> {
pub client: &'a Client,
}
#[allow(dead_code)]
#[derive(Deserialize)]
pub struct AccountPage {
first_page_uri: String,
end: u16,
previous_page_uri: Option<String>,
accounts: Vec<Account>,
uri: String,
page_size: u16,
start: u16,
next_page_uri: Option<String>,
page: u16,
}
#[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Account {
pub status: Status,
pub date_updated: String,
pub friendly_name: String,
pub owner_account_sid: String,
pub uri: String,
pub sid: String,
pub date_created: String,
#[serde(rename = "type")]
pub type_field: String,
}
impl fmt::Display for Account {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} - {}", self.sid, self.status)
}
}
#[derive(
AsRefStr,
Clone,
Display,
Default,
Debug,
EnumIter,
EnumString,
Serialize,
Deserialize,
PartialEq,
)]
#[serde(rename_all = "lowercase")]
pub enum Status {
#[default]
#[strum(to_string = "Active")]
Active,
#[strum(to_string = "Suspended")]
Suspended,
#[strum(to_string = "Closed")]
Closed,
}
impl Status {
pub fn as_str(&self) -> &'static str {
match self {
Status::Active => "active",
Status::Suspended => "suspended",
Status::Closed => "closed",
}
}
}
#[derive(Serialize)]
#[serde(rename_all(serialize = "PascalCase"))]
pub struct ListOrUpdateParams {
pub friendly_name: Option<String>,
pub status: Option<Status>,
}
#[derive(Serialize)]
#[serde(rename_all(serialize = "PascalCase"))]
pub struct CreateParams {
pub friendly_name: Option<String>,
}
impl Accounts<'_> {
pub async fn get(&self, sid: Option<&str>) -> Result<Account, TwilioError> {
self.client
.send_request::<Account, ()>(
Method::GET,
&format!(
"https://api.twilio.com/2010-04-01/Accounts/{}.json",
sid.unwrap_or_else(|| &self.client.config.account_sid)
),
None,
None,
)
.await
}
pub async fn list(
&self,
friendly_name: Option<&str>,
status: Option<&Status>,
) -> Result<Vec<Account>, TwilioError> {
let params = ListOrUpdateParams {
friendly_name: friendly_name.map(|friendly_name| friendly_name.to_string()),
status: status.cloned(),
};
let mut accounts_page = self
.client
.send_request::<AccountPage, ListOrUpdateParams>(
Method::GET,
"https://api.twilio.com/2010-04-01/Accounts.json?PageSize=5",
Some(¶ms),
None,
)
.await?;
let mut results: Vec<Account> = accounts_page.accounts;
while (accounts_page.next_page_uri).is_some() {
let full_url = format!(
"https://api.twilio.com{}",
accounts_page.next_page_uri.unwrap()
);
accounts_page = self
.client
.send_request::<AccountPage, ()>(Method::GET, &full_url, None, None)
.await?;
results.append(&mut accounts_page.accounts);
}
Ok(results)
}
pub async fn create(&self, friendly_name: Option<&str>) -> Result<Account, TwilioError> {
let params = CreateParams {
friendly_name: friendly_name.map(|friendly_name| friendly_name.to_string()),
};
self.client
.send_request::<Account, CreateParams>(
Method::POST,
"https://api.twilio.com/2010-04-01/Accounts.json",
Some(¶ms),
None,
)
.await
}
pub async fn update(
&self,
account_sid: &str,
friendly_name: Option<&str>,
status: Option<&Status>,
) -> Result<Account, TwilioError> {
let opts = ListOrUpdateParams {
friendly_name: friendly_name.map(|friendly_name| friendly_name.to_string()),
status: status.cloned(),
};
self.client
.send_request::<Account, ListOrUpdateParams>(
Method::POST,
&format!(
"https://api.twilio.com/2010-04-01/Accounts/{}.json",
account_sid
),
Some(&opts),
None,
)
.await
}
}