main
rs 142 lines 4.65 KB
Raw
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 }