main
rs 158 lines 5.49 KB
Raw
1 //! An `AppScreenshotSet` groups the screenshots for one device/display
2 //! class (e.g. Apple Vision Pro, iPhone 6.7") within one localization of an
3 //! `AppStoreVersion`. Screenshots themselves are a separate resource
4 //! ([`crate::app_screenshot`]) that belongs to a set.
5
6 use async_trait::async_trait;
7 use reqwest::Method;
8 use serde::{Deserialize, Serialize};
9 use smbcloud_ascapi_core::jsonapi::{
10 CreateBody, CreateData, Document, Resource, ResourceId, ToOne,
11 };
12 use smbcloud_ascapi_core::Client;
13 use smbcloud_ascapi_core::Result;
14
15 pub const RESOURCE_TYPE: &str = "appScreenshotSets";
16
17 /// The device/display class a screenshot set targets. Apple documents the
18 /// full set at
19 /// <https://developer.apple.com/documentation/appstoreconnectapi/screenshotdisplaytype>;
20 /// this covers the App Store (non-iMessage) display classes in current use.
21 #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
22 pub enum ScreenshotDisplayType {
23 #[serde(rename = "APP_APPLE_VISION_PRO")]
24 AppleVisionPro,
25 #[serde(rename = "APP_IPHONE_67")]
26 Iphone67,
27 #[serde(rename = "APP_IPHONE_65")]
28 Iphone65,
29 #[serde(rename = "APP_IPHONE_61")]
30 Iphone61,
31 #[serde(rename = "APP_IPHONE_58")]
32 Iphone58,
33 #[serde(rename = "APP_IPHONE_55")]
34 Iphone55,
35 #[serde(rename = "APP_IPHONE_47")]
36 Iphone47,
37 #[serde(rename = "APP_IPHONE_40")]
38 Iphone40,
39 #[serde(rename = "APP_IPHONE_35")]
40 Iphone35,
41 #[serde(rename = "APP_IPAD_PRO_3GEN_129")]
42 IpadPro3Gen129,
43 #[serde(rename = "APP_IPAD_PRO_3GEN_11")]
44 IpadPro3Gen11,
45 #[serde(rename = "APP_IPAD_PRO_129")]
46 IpadPro129,
47 #[serde(rename = "APP_IPAD_105")]
48 Ipad105,
49 #[serde(rename = "APP_IPAD_97")]
50 Ipad97,
51 #[serde(rename = "APP_DESKTOP")]
52 Desktop,
53 #[serde(rename = "APP_APPLE_TV")]
54 AppleTv,
55 #[serde(rename = "APP_WATCH_ULTRA")]
56 WatchUltra,
57 #[serde(rename = "APP_WATCH_SERIES_10")]
58 WatchSeries10,
59 #[serde(rename = "APP_WATCH_SERIES_7")]
60 WatchSeries7,
61 #[serde(rename = "APP_WATCH_SERIES_4")]
62 WatchSeries4,
63 #[serde(rename = "APP_WATCH_SERIES_3")]
64 WatchSeries3,
65 }
66
67 #[derive(Debug, Clone, Serialize, Deserialize)]
68 #[serde(rename_all = "camelCase")]
69 pub struct AppScreenshotSetAttributes {
70 pub screenshot_display_type: ScreenshotDisplayType,
71 }
72
73 pub type AppScreenshotSet = Resource<AppScreenshotSetAttributes>;
74
75 #[derive(Debug, Clone, Serialize)]
76 #[serde(rename_all = "camelCase")]
77 pub struct AppScreenshotSetCreateAttributes {
78 pub screenshot_display_type: ScreenshotDisplayType,
79 }
80
81 #[derive(Debug, Clone, Serialize)]
82 #[serde(rename_all = "camelCase")]
83 pub struct AppScreenshotSetRelationships {
84 pub app_store_version_localization: ToOne,
85 }
86
87 /// Per-device-class screenshot buckets.
88 ///
89 /// An extension trait rather than inherent methods, because `Client`
90 /// lives in the core crate and Rust only allows inherent impls in the
91 /// crate that defines the type. Import it, or the crate's `prelude`,
92 /// to call these on a `Client`.
93 #[async_trait]
94 pub trait AppScreenshotSetsApi {
95 /// `GET /v1/appStoreVersionLocalizations/{id}/appScreenshotSets`.
96 async fn list_app_screenshot_sets(
97 &self,
98 app_store_version_localization_id: &str,
99 ) -> Result<Vec<AppScreenshotSet>>;
100
101 /// `POST /v1/appScreenshotSets` — adds a device/display class's
102 /// screenshot bucket to a localization. Screenshots are then added to
103 /// the returned set with [`AppScreenshotsApi::create_app_screenshot`](crate::app_screenshot::AppScreenshotsApi::create_app_screenshot) /
104 /// [`AppScreenshotsApi::upload_app_screenshot`](crate::app_screenshot::AppScreenshotsApi::upload_app_screenshot).
105 async fn create_app_screenshot_set(
106 &self,
107 app_store_version_localization_id: &str,
108 attributes: AppScreenshotSetCreateAttributes,
109 ) -> Result<AppScreenshotSet>;
110
111 /// `DELETE /v1/appScreenshotSets/{id}`.
112 async fn delete_app_screenshot_set(&self, id: &str) -> Result<()>;
113 }
114
115 #[async_trait]
116 impl AppScreenshotSetsApi for Client {
117 async fn list_app_screenshot_sets(
118 &self,
119 app_store_version_localization_id: &str,
120 ) -> Result<Vec<AppScreenshotSet>> {
121 let path = format!(
122 "/v1/appStoreVersionLocalizations/{app_store_version_localization_id}/appScreenshotSets"
123 );
124 self.list_all::<AppScreenshotSetAttributes>(&path, &[])
125 .await
126 }
127
128 async fn create_app_screenshot_set(
129 &self,
130 app_store_version_localization_id: &str,
131 attributes: AppScreenshotSetCreateAttributes,
132 ) -> Result<AppScreenshotSet> {
133 let body = CreateBody {
134 data: CreateData {
135 resource_type: RESOURCE_TYPE,
136 attributes,
137 relationships: Some(AppScreenshotSetRelationships {
138 app_store_version_localization: ToOne {
139 data: ResourceId {
140 resource_type: crate::app_store_version_localization::RESOURCE_TYPE,
141 id: app_store_version_localization_id.to_string(),
142 },
143 },
144 }),
145 },
146 };
147 let doc: Document<AppScreenshotSetAttributes> = self
148 .request(Method::POST, "/v1/appScreenshotSets", &[], Some(&body))
149 .await?;
150 Ok(doc.data)
151 }
152
153 async fn delete_app_screenshot_set(&self, id: &str) -> Result<()> {
154 let path = format!("/v1/appScreenshotSets/{id}");
155 self.request_no_content::<()>(Method::DELETE, &path, &[], None)
156 .await
157 }
158 }