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 MapItemPage {
pub items: Vec<SyncMapItem>,
pub meta: PageMeta,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct SyncMapItem {
pub key: String,
pub account_sid: String,
pub service_sid: String,
pub map_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 revision: String,
}
pub struct CreateParams<'a, T>
where
T: ?Sized + Serialize,
{
pub key: String,
pub data: &'a T,
pub ttl: Option<u16>,
pub collection_ttl: Option<u16>,
}
#[skip_serializing_none]
#[derive(Serialize)]
#[serde(rename_all(serialize = "PascalCase"))]
struct CreateParamsWithJson {
key: String,
data: String,
ttl: Option<u16>,
collection_ttl: Option<u16>,
}
#[derive(Serialize)]
pub enum Order {
Asc,
Desc,
}
#[derive(Serialize)]
pub enum Bounds {
Inclusive,
Exclusive,
}
#[skip_serializing_none]
#[derive(Serialize)]
#[serde(rename_all(serialize = "PascalCase"))]
pub struct ListParams {
pub order: Option<Order>,
pub from: Option<String>,
pub bounds: Option<Bounds>,
}
pub struct UpdateParams<'a, T>
where
T: ?Sized + Serialize,
{
pub if_match: Option<String>,
pub data: &'a T,
pub ttl: Option<u16>,
pub collection_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>,
collection_ttl: Option<u16>,
}
pub struct MapItems<'a, 'b> {
pub client: &'a Client,
pub service_sid: &'b str,
pub map_sid: &'b str,
}
impl MapItems<'_, '_> {
pub async fn create<T>(&self, params: CreateParams<'_, T>) -> Result<SyncMapItem, TwilioError>
where
T: ?Sized + Serialize,
{
let params = CreateParamsWithJson {
key: params.key,
data: serde_json::to_string(params.data)
.expect("Unable to convert provided data value to a JSON string"),
ttl: params.ttl,
collection_ttl: params.collection_ttl,
};
self.client
.send_request::<SyncMapItem, CreateParamsWithJson>(
Method::POST,
&format!(
"https://sync.twilio.com/v1/Services/{}/Maps/{}/Items",
self.service_sid, self.map_sid
),
Some(¶ms),
None,
)
.await
}
pub async fn list(&self, params: ListParams) -> Result<Vec<SyncMapItem>, TwilioError> {
let mut map_items_page = self
.client
.send_request::<MapItemPage, ListParams>(
Method::GET,
&format!(
"https://sync.twilio.com/v1/Services/{}/Maps/{}/Items?PageSize=50",
self.service_sid, self.map_sid
),
Some(¶ms),
None,
)
.await?;
let mut results: Vec<SyncMapItem> = map_items_page.items;
while (map_items_page.meta.next_page_url).is_some() {
map_items_page = self
.client
.send_request::<MapItemPage, ListParams>(
Method::GET,
&map_items_page.meta.next_page_url.unwrap(),
None,
None,
)
.await?;
results.append(&mut map_items_page.items);
}
Ok(results)
}
}
pub struct MapItem<'a, 'b> {
pub client: &'a Client,
pub service_sid: &'b str,
pub map_sid: &'b str,
pub key: &'b str,
}
impl MapItem<'_, '_> {
pub async fn get(&self) -> Result<SyncMapItem, TwilioError> {
self.client
.send_request::<SyncMapItem, ()>(
Method::GET,
&format!(
"https://sync.twilio.com/v1/Services/{}/Maps/{}/Items/{}",
self.service_sid, self.map_sid, self.key
),
None,
None,
)
.await
}
pub async fn update<T>(&self, params: UpdateParams<'_, T>) -> Result<SyncMapItem, 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,
collection_ttl: params.collection_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::<SyncMapItem, UpdateParamsWithJson>(
Method::POST,
&format!(
"https://sync.twilio.com/v1/Services/{}/Maps/{}/Items/{}",
self.service_sid, self.map_sid, self.key
),
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/{}/Maps/{}/Items/{}",
self.service_sid, self.map_sid, self.key
),
None,
None,
)
.await
}
}