development
rs 57 lines 2.19 KB
Raw
1 //! An `AppInfo` is the platform-independent, category/age-rating side of an
2 //! app's metadata; its localized name/subtitle live on
3 //! [`crate::app_info_localization`]. App Store Connect creates and manages
4 //! `AppInfo` rows itself (there is no create/delete endpoint) — this module
5 //! only reads them and updates category/age-rating relationships.
6
7 use async_trait::async_trait;
8 use reqwest::Method;
9 use serde::{Deserialize, Serialize};
10 use smbcloud_ascapi_core::jsonapi::{Document, Resource};
11 use smbcloud_ascapi_core::Client;
12 use smbcloud_ascapi_core::Result;
13
14 pub const RESOURCE_TYPE: &str = "appInfos";
15
16 #[derive(Debug, Clone, Serialize, Deserialize)]
17 #[serde(rename_all = "camelCase")]
18 pub struct AppInfoAttributes {
19 pub app_store_state: Option<String>,
20 pub app_store_age_rating: Option<String>,
21 pub brazil_age_rating: Option<String>,
22 pub kids_age_band: Option<String>,
23 }
24
25 pub type AppInfo = Resource<AppInfoAttributes>;
26
27 /// AppInfos: the container for localized names and subtitles.
28 ///
29 /// An extension trait rather than inherent methods, because `Client`
30 /// lives in the core crate and Rust only allows inherent impls in the
31 /// crate that defines the type. Import it, or the crate's `prelude`,
32 /// to call these on a `Client`.
33 #[async_trait]
34 pub trait AppInfosApi {
35 /// `GET /v1/apps/{app_id}/appInfos`. An app usually has one current
36 /// `AppInfo` (plus, briefly, a second pending one while an edit awaits
37 /// review) — this is the parent resource `AppInfoLocalization`s hang
38 /// off of, and the id you need for `create_app_info_localization`.
39 async fn list_app_infos(&self, app_id: &str) -> Result<Vec<AppInfo>>;
40
41 async fn get_app_info(&self, id: &str) -> Result<AppInfo>;
42 }
43
44 #[async_trait]
45 impl AppInfosApi for Client {
46 async fn list_app_infos(&self, app_id: &str) -> Result<Vec<AppInfo>> {
47 let path = format!("/v1/apps/{app_id}/appInfos");
48 self.list_all::<AppInfoAttributes>(&path, &[]).await
49 }
50
51 async fn get_app_info(&self, id: &str) -> Result<AppInfo> {
52 let path = format!("/v1/appInfos/{id}");
53 let doc: Document<AppInfoAttributes> =
54 self.request(Method::GET, &path, &[], None::<&()>).await?;
55 Ok(doc.data)
56 }
57 }