use crate::{Client, PageMeta, TwilioError};
use reqwest::Method;
use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
use super::{
documents::{Document, Documents},
lists::{List, Lists},
maps::{Map, Maps},
};
#[allow(dead_code)]
#[derive(Deserialize)]
pub struct SyncServicePage {
services: Vec<SyncService>,
meta: PageMeta,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct SyncService {
pub sid: String,
pub unique_name: Option<String>,
pub account_sid: String,
pub friendly_name: Option<String>,
pub date_created: String,
pub date_updated: String,
pub url: String,
pub webhook_url: Option<String>,
pub webhooks_from_rest_enabled: bool,
pub acl_enabled: bool,
pub reachability_debouncing_enabled: bool,
pub reachability_debouncing_window: u16,
pub links: Links,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq)]
pub struct Links {
pub documents: String,
pub lists: String,
pub maps: String,
pub streams: String,
}
#[skip_serializing_none]
#[derive(Serialize)]
#[serde(rename_all(serialize = "PascalCase"))]
pub struct CreateOrUpdateParams {
pub friendly_name: Option<String>,
pub webhook_url: Option<String>,
pub reachability_webhooks_enabled: Option<bool>,
pub acl_enabled: Option<bool>,
pub reachability_debouncing_enabled: Option<bool>,
pub reachability_debouncing_window: Option<u16>,
pub webhooks_from_rest_enabled: Option<bool>,
}
pub struct Services<'a> {
pub client: &'a Client,
}
impl Services<'_> {
pub async fn create(&self, params: CreateOrUpdateParams) -> Result<SyncService, TwilioError> {
if let Some(reachability_debouncing_window) = params.reachability_debouncing_window {
let validation =
validate_reachability_debouncing_window(reachability_debouncing_window);
validation?
}
self.client
.send_request::<SyncService, CreateOrUpdateParams>(
Method::POST,
"https://sync.twilio.com/v1/Services",
Some(¶ms),
None,
)
.await
}
pub async fn list(&self) -> Result<Vec<SyncService>, TwilioError> {
let mut services_page = self
.client
.send_request::<SyncServicePage, ()>(
Method::GET,
"https://sync.twilio.com/v1/Services?PageSize=20",
None,
None,
)
.await?;
let mut results: Vec<SyncService> = services_page.services;
while (services_page.meta.next_page_url).is_some() {
services_page = self
.client
.send_request::<SyncServicePage, ()>(
Method::GET,
&services_page.meta.next_page_url.unwrap(),
None,
None,
)
.await?;
results.append(&mut services_page.services);
}
Ok(results)
}
}
pub struct Service<'a, 'b> {
pub client: &'a Client,
pub sid: &'b str,
}
impl<'b> Service<'_, 'b> {
pub async fn get(&self) -> Result<SyncService, TwilioError> {
self.client
.send_request::<SyncService, ()>(
Method::GET,
&format!("https://sync.twilio.com/v1/Services/{}", self.sid),
None,
None,
)
.await
}
pub async fn update(&self, params: CreateOrUpdateParams) -> Result<SyncService, TwilioError> {
if let Some(reachability_debouncing_window) = params.reachability_debouncing_window {
let validation =
validate_reachability_debouncing_window(reachability_debouncing_window);
validation?
}
self.client
.send_request::<SyncService, CreateOrUpdateParams>(
Method::POST,
&format!("https://sync.twilio.com/v1/Services/{}", self.sid),
Some(¶ms),
None,
)
.await
}
pub async fn delete(&self) -> Result<(), TwilioError> {
self.client
.send_request_and_ignore_response::<()>(
Method::DELETE,
&format!("https://sync.twilio.com/v1/Services/{}", self.sid),
None,
None,
)
.await
}
pub fn document(&self, sid: &'b str) -> Document {
Document {
client: self.client,
service_sid: self.sid,
sid,
}
}
pub fn documents(&self) -> Documents {
Documents {
client: self.client,
service_sid: self.sid,
}
}
pub fn map(&self, sid: &'b str) -> Map {
Map {
client: self.client,
service_sid: self.sid,
sid,
}
}
pub fn maps(&self) -> Maps {
Maps {
client: self.client,
service_sid: self.sid,
}
}
pub fn lists(&self) -> Lists {
Lists {
client: self.client,
service_sid: self.sid,
}
}
pub fn list(&self, sid: &'b str) -> List {
List {
client: self.client,
service_sid: self.sid,
sid,
}
}
}
fn validate_reachability_debouncing_window(
reachability_debouncing_window: u16,
) -> Result<(), TwilioError> {
if reachability_debouncing_window < 1000 {
return Err(TwilioError {
kind: crate::ErrorKind::ValidationError(String::from(
"Reachability debouncing window must be greater than 1000 milliseconds",
)),
});
} else if reachability_debouncing_window > 30000 {
return Err(TwilioError {
kind: crate::ErrorKind::ValidationError(String::from(
"Reachability debouncing window must be less than 30,000 milliseconds",
)),
});
}
Ok(())
}