Skip to main content

smbcloud_ascapi_aso/
app_info.rs

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
7use async_trait::async_trait;
8use reqwest::Method;
9use serde::{Deserialize, Serialize};
10use smbcloud_ascapi_core::jsonapi::{Document, Resource};
11use smbcloud_ascapi_core::Client;
12use smbcloud_ascapi_core::Result;
13
14pub const RESOURCE_TYPE: &str = "appInfos";
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
17#[serde(rename_all = "camelCase")]
18pub 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
25pub 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]
34pub 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]
45impl 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}