use async_trait::async_trait;
use reqwest::Method;
use serde::{Deserialize, Serialize};
use smbcloud_ascapi_core::jsonapi::{CreateBody, CreateData, Document, ListDocument, Resource};
use smbcloud_ascapi_core::Client;
use smbcloud_ascapi_core::Result;
pub const RESOURCE_TYPE: &str = "bundleIds";
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum BundleIdPlatform {
#[serde(rename = "IOS")]
Ios,
#[serde(rename = "MAC_OS")]
MacOs,
#[serde(rename = "UNIVERSAL")]
Universal,
#[serde(rename = "SERVICES")]
Services,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct BundleIdAttributes {
pub name: Option<String>,
pub identifier: Option<String>,
pub platform: Option<BundleIdPlatform>,
pub seed_id: Option<String>,
}
pub type BundleId = Resource<BundleIdAttributes>;
#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BundleIdCreateAttributes {
pub identifier: String,
pub name: String,
pub platform: BundleIdPlatform,
}
#[async_trait]
pub trait BundleIdsApi {
async fn list_bundle_ids(&self, filter_identifier: Option<&str>) -> Result<Vec<BundleId>>;
async fn create_bundle_id(&self, attributes: BundleIdCreateAttributes) -> Result<BundleId>;
}
#[async_trait]
impl BundleIdsApi for Client {
async fn list_bundle_ids(&self, filter_identifier: Option<&str>) -> Result<Vec<BundleId>> {
let mut query = Vec::new();
if let Some(identifier) = filter_identifier {
query.push(("filter[identifier]", identifier));
}
query.push(("limit", "200"));
let doc: ListDocument<BundleIdAttributes> = self
.request(Method::GET, "/v1/bundleIds", &query, None::<&()>)
.await?;
Ok(doc.data)
}
async fn create_bundle_id(&self, attributes: BundleIdCreateAttributes) -> Result<BundleId> {
let body = CreateBody {
data: CreateData {
resource_type: RESOURCE_TYPE,
attributes,
relationships: None::<()>,
},
};
let doc: Document<BundleIdAttributes> = self
.request(Method::POST, "/v1/bundleIds", &[], Some(&body))
.await?;
Ok(doc.data)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn a_services_identifier_does_not_break_the_list() {
let body = serde_json::json!({
"data": [
{
"id": "AAA",
"type": "bundleIds",
"attributes": {
"name": "An app",
"identifier": "xyz.example.app",
"platform": "UNIVERSAL",
"seedId": "TEAMID"
}
},
{
"id": "BBB",
"type": "bundleIds",
"attributes": {
"name": "Sign in with Apple",
"identifier": "xyz.example.service",
"platform": "SERVICES",
"seedId": "TEAMID"
}
}
]
});
let doc: ListDocument<BundleIdAttributes> =
serde_json::from_value(body).expect("a Services identifier must not fail the list");
assert_eq!(doc.data.len(), 2);
assert_eq!(
doc.data[1].attributes.platform,
Some(BundleIdPlatform::Services)
);
}
}