| 1 | use async_trait::async_trait; |
| 2 | use reqwest::Method; |
| 3 | use serde::{Deserialize, Serialize}; |
| 4 | use smbcloud_ascapi_core::jsonapi::{ |
| 5 | CreateBody, CreateData, Document, Resource, ResourceId, ToOne, UpdateBody, UpdateData, |
| 6 | }; |
| 7 | use smbcloud_ascapi_core::Client; |
| 8 | use smbcloud_ascapi_core::Result; |
| 9 | |
| 10 | pub const RESOURCE_TYPE: &str = "appInfoLocalizations"; |
| 11 | |
| 12 | #[derive(Debug, Clone, Serialize, Deserialize)] |
| 13 | #[serde(rename_all = "camelCase")] |
| 14 | pub struct AppInfoLocalizationAttributes { |
| 15 | pub locale: String, |
| 16 | pub name: Option<String>, |
| 17 | pub subtitle: Option<String>, |
| 18 | pub privacy_policy_url: Option<String>, |
| 19 | pub privacy_choices_url: Option<String>, |
| 20 | pub privacy_policy_text: Option<String>, |
| 21 | } |
| 22 | |
| 23 | pub type AppInfoLocalization = Resource<AppInfoLocalizationAttributes>; |
| 24 | |
| 25 | #[derive(Debug, Clone, Serialize)] |
| 26 | #[serde(rename_all = "camelCase")] |
| 27 | pub struct AppInfoLocalizationCreateAttributes { |
| 28 | pub locale: String, |
| 29 | pub name: String, |
| 30 | #[serde(skip_serializing_if = "Option::is_none")] |
| 31 | pub subtitle: Option<String>, |
| 32 | #[serde(skip_serializing_if = "Option::is_none")] |
| 33 | pub privacy_policy_url: Option<String>, |
| 34 | } |
| 35 | |
| 36 | #[derive(Debug, Clone, Default, Serialize)] |
| 37 | #[serde(rename_all = "camelCase")] |
| 38 | pub struct AppInfoLocalizationUpdateAttributes { |
| 39 | #[serde(skip_serializing_if = "Option::is_none")] |
| 40 | pub name: Option<String>, |
| 41 | #[serde(skip_serializing_if = "Option::is_none")] |
| 42 | pub subtitle: Option<String>, |
| 43 | #[serde(skip_serializing_if = "Option::is_none")] |
| 44 | pub privacy_policy_url: Option<String>, |
| 45 | } |
| 46 | |
| 47 | #[derive(Debug, Clone, Serialize)] |
| 48 | #[serde(rename_all = "camelCase")] |
| 49 | pub struct AppInfoLocalizationRelationships { |
| 50 | pub app_info: ToOne, |
| 51 | } |
| 52 | |
| 53 | /// Per-locale app name, subtitle, and privacy policy URL. |
| 54 | /// |
| 55 | /// An extension trait rather than inherent methods, because `Client` |
| 56 | /// lives in the core crate and Rust only allows inherent impls in the |
| 57 | /// crate that defines the type. Import it, or the crate's `prelude`, |
| 58 | /// to call these on a `Client`. |
| 59 | #[async_trait] |
| 60 | pub trait AppInfoLocalizationsApi { |
| 61 | async fn list_app_info_localizations( |
| 62 | &self, |
| 63 | app_info_id: &str, |
| 64 | ) -> Result<Vec<AppInfoLocalization>>; |
| 65 | |
| 66 | /// `POST /v1/appInfoLocalizations` — adds a locale's name/subtitle to an |
| 67 | /// `AppInfo`. |
| 68 | async fn create_app_info_localization( |
| 69 | &self, |
| 70 | app_info_id: &str, |
| 71 | attributes: AppInfoLocalizationCreateAttributes, |
| 72 | ) -> Result<AppInfoLocalization>; |
| 73 | |
| 74 | async fn update_app_info_localization( |
| 75 | &self, |
| 76 | id: &str, |
| 77 | attributes: AppInfoLocalizationUpdateAttributes, |
| 78 | ) -> Result<AppInfoLocalization>; |
| 79 | |
| 80 | async fn delete_app_info_localization(&self, id: &str) -> Result<()>; |
| 81 | } |
| 82 | |
| 83 | #[async_trait] |
| 84 | impl AppInfoLocalizationsApi for Client { |
| 85 | async fn list_app_info_localizations( |
| 86 | &self, |
| 87 | app_info_id: &str, |
| 88 | ) -> Result<Vec<AppInfoLocalization>> { |
| 89 | let path = format!("/v1/appInfos/{app_info_id}/appInfoLocalizations"); |
| 90 | self.list_all::<AppInfoLocalizationAttributes>(&path, &[]) |
| 91 | .await |
| 92 | } |
| 93 | |
| 94 | async fn create_app_info_localization( |
| 95 | &self, |
| 96 | app_info_id: &str, |
| 97 | attributes: AppInfoLocalizationCreateAttributes, |
| 98 | ) -> Result<AppInfoLocalization> { |
| 99 | let body = CreateBody { |
| 100 | data: CreateData { |
| 101 | resource_type: RESOURCE_TYPE, |
| 102 | attributes, |
| 103 | relationships: Some(AppInfoLocalizationRelationships { |
| 104 | app_info: ToOne { |
| 105 | data: ResourceId { |
| 106 | resource_type: crate::app_info::RESOURCE_TYPE, |
| 107 | id: app_info_id.to_string(), |
| 108 | }, |
| 109 | }, |
| 110 | }), |
| 111 | }, |
| 112 | }; |
| 113 | let doc: Document<AppInfoLocalizationAttributes> = self |
| 114 | .request(Method::POST, "/v1/appInfoLocalizations", &[], Some(&body)) |
| 115 | .await?; |
| 116 | Ok(doc.data) |
| 117 | } |
| 118 | |
| 119 | async fn update_app_info_localization( |
| 120 | &self, |
| 121 | id: &str, |
| 122 | attributes: AppInfoLocalizationUpdateAttributes, |
| 123 | ) -> Result<AppInfoLocalization> { |
| 124 | let path = format!("/v1/appInfoLocalizations/{id}"); |
| 125 | let body = UpdateBody { |
| 126 | data: UpdateData { |
| 127 | resource_type: RESOURCE_TYPE, |
| 128 | id: id.to_string(), |
| 129 | attributes, |
| 130 | }, |
| 131 | }; |
| 132 | let doc: Document<AppInfoLocalizationAttributes> = |
| 133 | self.request(Method::PATCH, &path, &[], Some(&body)).await?; |
| 134 | Ok(doc.data) |
| 135 | } |
| 136 | |
| 137 | async fn delete_app_info_localization(&self, id: &str) -> Result<()> { |
| 138 | let path = format!("/v1/appInfoLocalizations/{id}"); |
| 139 | self.request_no_content::<()>(Method::DELETE, &path, &[], None) |
| 140 | .await |
| 141 | } |
| 142 | } |