use crate::{Client, PageMeta, TwilioError};
use reqwest::{header::HeaderMap, Method};
use serde::{Deserialize, Serialize};
use serde_json::Value;
use serde_with::skip_serializing_none;
#[allow(dead_code)]
#[derive(Deserialize)]
pub struct DocumentPage {
documents: Vec<SyncDocument>,
meta: PageMeta,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct SyncDocument {
pub sid: String,
pub unique_name: String,
pub account_sid: String,
pub service_sid: String,
pub url: String,
pub data: Value,
pub date_created: String,
pub date_updated: String,
pub date_expires: Option<String>,
pub created_by: String,
pub links: Links,
pub revision: String,
}
#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq)]
pub struct Links {
pub permissions: String,
}
pub struct CreateParams<'a, T>
where
T: ?Sized + Serialize,
{
pub unique_name: Option<String>,
pub data: &'a T,
pub ttl: Option<u16>,
}
#[skip_serializing_none]
#[derive(Serialize)]
#[serde(rename_all(serialize = "PascalCase"))]
struct CreateParamsWithJson {
unique_name: Option<String>,
data: String,
ttl: Option<u16>,
}
pub struct UpdateParams<'a, T>
where
T: ?Sized + Serialize,
{
pub if_match: Option<String>,
pub data: &'a T,
pub ttl: Option<u16>,
}
#[skip_serializing_none]
#[derive(Serialize)]
#[serde(rename_all(serialize = "PascalCase"))]
struct UpdateParamsWithJson {
#[serde(rename(serialize = "If-Match"))]
if_match: Option<String>,
data: String,
ttl: Option<u16>,
}
pub struct Documents<'a, 'b> {
pub client: &'a Client,
pub service_sid: &'b str,
}
impl Documents<'_, '_> {
pub async fn create<T>(&self, params: CreateParams<'_, T>) -> Result<SyncDocument, TwilioError>
where
T: ?Sized + Serialize,
{
let params = CreateParamsWithJson {
unique_name: params.unique_name,
data: serde_json::to_string(params.data)
.expect("Unable to convert provided data value to a JSON string"),
ttl: params.ttl,
};
self.client
.send_request::<SyncDocument, CreateParamsWithJson>(
Method::POST,
&format!(
"https://sync.twilio.com/v1/Services/{}/Documents",
self.service_sid
),
Some(¶ms),
None,
)
.await
}
pub async fn list(&self) -> Result<Vec<SyncDocument>, TwilioError> {
let mut documents_page = self
.client
.send_request::<DocumentPage, ()>(
Method::GET,
&format!(
"https://sync.twilio.com/v1/Services/{}/Documents?PageSize=50",
self.service_sid
),
None,
None,
)
.await?;
let mut results: Vec<SyncDocument> = documents_page.documents;
while (documents_page.meta.next_page_url).is_some() {
documents_page = self
.client
.send_request::<DocumentPage, ()>(
Method::GET,
&documents_page.meta.next_page_url.unwrap(),
None,
None,
)
.await?;
results.append(&mut documents_page.documents);
}
Ok(results)
}
}
pub struct Document<'a, 'b> {
pub client: &'a Client,
pub service_sid: &'b str,
pub sid: &'b str,
}
impl Document<'_, '_> {
pub async fn get(&self) -> Result<SyncDocument, TwilioError> {
self.client
.send_request::<SyncDocument, ()>(
Method::GET,
&format!(
"https://sync.twilio.com/v1/Services/{}/Documents/{}",
self.service_sid, self.sid
),
None,
None,
)
.await
}
pub async fn update<T>(&self, params: UpdateParams<'_, T>) -> Result<SyncDocument, TwilioError>
where
T: ?Sized + Serialize,
{
let params = UpdateParamsWithJson {
if_match: params.if_match,
data: serde_json::to_string(params.data)
.expect("Unable to convert provided data value to a JSON string"),
ttl: params.ttl,
};
let mut headers = HeaderMap::new();
if let Some(if_match) = params.if_match.clone() {
headers.append("If-Match", if_match.parse().unwrap());
}
self.client
.send_request::<SyncDocument, UpdateParamsWithJson>(
Method::POST,
&format!(
"https://sync.twilio.com/v1/Services/{}/Documents/{}",
self.service_sid, self.sid
),
Some(¶ms),
Some(headers),
)
.await
}
pub async fn delete(&self) -> Result<(), TwilioError> {
self.client
.send_request_and_ignore_response::<()>(
Method::DELETE,
&format!(
"https://sync.twilio.com/v1/Services/{}/Documents/{}",
self.service_sid, self.sid
),
None,
None,
)
.await
}
}