Skip to main content

egs_api/facade/
fab.rs

1use crate::EpicGames;
2use crate::api::error::EpicAPIError;
3use crate::api::types::download_manifest::DownloadManifest;
4use crate::api::types::fab_asset_manifest::DownloadInfo;
5use crate::api::types::fab_entitlement;
6use crate::api::types::fab_search;
7use crate::api::types::fab_taxonomy;
8
9impl EpicGames {
10    /// Fetch Fab asset manifest with signed distribution points.
11    ///
12    /// Returns `Result` to expose timeout errors (403 → `EpicAPIError::FabTimeout`).
13    pub async fn fab_asset_manifest(
14        &self,
15        artifact_id: &str,
16        namespace: &str,
17        asset_id: &str,
18        platform: Option<&str>,
19    ) -> Result<Vec<DownloadInfo>, EpicAPIError> {
20        match self
21            .egs
22            .fab_asset_manifest(artifact_id, namespace, asset_id, platform)
23            .await
24        {
25            Ok(a) => Ok(a),
26            Err(e) => Err(e),
27        }
28    }
29
30    /// Like [`fab_library_items`](Self::fab_library_items), but returns a `Result` instead of swallowing errors.
31    pub async fn try_fab_library_items(
32        &mut self,
33        account_id: String,
34    ) -> Result<crate::api::types::fab_library::FabLibrary, EpicAPIError> {
35        self.egs.fab_library_items(account_id).await
36    }
37
38    /// Fetch the user Fab library.
39    ///
40    /// Paginates internally and returns all records at once. Returns `None` on API errors.
41    pub async fn fab_library_items(
42        &mut self,
43        account_id: String,
44    ) -> Option<crate::api::types::fab_library::FabLibrary> {
45        self.try_fab_library_items(account_id).await.ok()
46    }
47
48    /// Parse a Fab download manifest from a specific distribution point.
49    ///
50    /// Checks signature expiration before fetching. Returns `Result` to expose timeout errors.
51    pub async fn fab_download_manifest(
52        &self,
53        download_info: DownloadInfo,
54        distribution_point_url: &str,
55    ) -> Result<DownloadManifest, EpicAPIError> {
56        self.egs
57            .fab_download_manifest(download_info, distribution_point_url)
58            .await
59    }
60
61    /// Like [`fab_file_download_info`](Self::fab_file_download_info), but returns a `Result` instead of swallowing errors.
62    pub async fn try_fab_file_download_info(
63        &self,
64        listing_id: &str,
65        format_id: &str,
66        file_id: &str,
67    ) -> Result<DownloadInfo, EpicAPIError> {
68        self.egs
69            .fab_file_download_info(listing_id, format_id, file_id)
70            .await
71    }
72
73    /// Fetch download info for a specific file within a Fab listing.
74    ///
75    /// Returns signed [`DownloadInfo`] for a single file identified by
76    /// `listing_id`, `format_id`, and `file_id`. Use this for targeted
77    /// downloads of individual files from a Fab asset rather than fetching
78    /// the entire asset manifest.
79    ///
80    /// Returns `None` on API errors.
81    pub async fn fab_file_download_info(
82        &self,
83        listing_id: &str,
84        format_id: &str,
85        file_id: &str,
86    ) -> Option<DownloadInfo> {
87        self.try_fab_file_download_info(listing_id, format_id, file_id)
88            .await
89            .ok()
90    }
91
92    // ── Fab Search/Browse ──
93
94    /// Search Fab listings. Returns `None` on error.
95    pub async fn fab_search(
96        &self,
97        params: &fab_search::FabSearchParams,
98    ) -> Option<fab_search::FabSearchResults> {
99        self.egs.fab_search(params).await.ok()
100    }
101
102    /// Search Fab listings. Returns full `Result`.
103    pub async fn try_fab_search(
104        &self,
105        params: &fab_search::FabSearchParams,
106    ) -> Result<fab_search::FabSearchResults, EpicAPIError> {
107        self.egs.fab_search(params).await
108    }
109
110    /// Get full listing detail. Returns `None` on error.
111    pub async fn fab_listing(&self, uid: &str) -> Option<fab_search::FabListingDetail> {
112        self.egs.fab_listing(uid).await.ok()
113    }
114
115    /// Get full listing detail. Returns full `Result`.
116    pub async fn try_fab_listing(
117        &self,
118        uid: &str,
119    ) -> Result<fab_search::FabListingDetail, EpicAPIError> {
120        self.egs.fab_listing(uid).await
121    }
122
123    /// Get UE-specific format details for a listing. Returns `None` on error.
124    pub async fn fab_listing_ue_formats(
125        &self,
126        uid: &str,
127    ) -> Option<Vec<fab_search::FabListingUeFormat>> {
128        self.egs.fab_listing_ue_formats(uid).await.ok()
129    }
130
131    /// Get UE-specific format details. Returns full `Result`.
132    pub async fn try_fab_listing_ue_formats(
133        &self,
134        uid: &str,
135    ) -> Result<Vec<fab_search::FabListingUeFormat>, EpicAPIError> {
136        self.egs.fab_listing_ue_formats(uid).await
137    }
138
139    /// Get listing state (ownership, wishlist, review). Returns `None` on error.
140    pub async fn fab_listing_state(&self, uid: &str) -> Option<fab_search::FabListingState> {
141        self.egs.fab_listing_state(uid).await.ok()
142    }
143
144    /// Get listing state. Returns full `Result`.
145    pub async fn try_fab_listing_state(
146        &self,
147        uid: &str,
148    ) -> Result<fab_search::FabListingState, EpicAPIError> {
149        self.egs.fab_listing_state(uid).await
150    }
151
152    /// Bulk check listing states. Returns `None` on error.
153    pub async fn fab_listing_states_bulk(
154        &self,
155        listing_ids: &[&str],
156    ) -> Option<Vec<fab_search::FabListingState>> {
157        self.egs.fab_listing_states_bulk(listing_ids).await.ok()
158    }
159
160    /// Bulk check listing states. Returns full `Result`.
161    pub async fn try_fab_listing_states_bulk(
162        &self,
163        listing_ids: &[&str],
164    ) -> Result<Vec<fab_search::FabListingState>, EpicAPIError> {
165        self.egs.fab_listing_states_bulk(listing_ids).await
166    }
167
168    /// Bulk fetch pricing for multiple offer IDs. Returns `None` on error.
169    pub async fn fab_bulk_prices(
170        &self,
171        offer_ids: &[&str],
172    ) -> Option<fab_search::FabBulkPricesResponse> {
173        self.egs.fab_bulk_prices(offer_ids).await.ok()
174    }
175
176    /// Bulk fetch pricing. Returns full `Result`.
177    pub async fn try_fab_bulk_prices(
178        &self,
179        offer_ids: &[&str],
180    ) -> Result<fab_search::FabBulkPricesResponse, EpicAPIError> {
181        self.egs.fab_bulk_prices(offer_ids).await
182    }
183
184    /// Get listing ownership info. Returns `None` on error.
185    pub async fn fab_listing_ownership(&self, uid: &str) -> Option<fab_search::FabOwnership> {
186        self.egs.fab_listing_ownership(uid).await.ok()
187    }
188
189    /// Get listing ownership info. Returns full `Result`.
190    pub async fn try_fab_listing_ownership(
191        &self,
192        uid: &str,
193    ) -> Result<fab_search::FabOwnership, EpicAPIError> {
194        self.egs.fab_listing_ownership(uid).await
195    }
196
197    /// Get pricing for a specific listing. Returns `None` on error.
198    pub async fn fab_listing_prices(&self, uid: &str) -> Option<Vec<fab_search::FabPriceInfo>> {
199        self.egs.fab_listing_prices(uid).await.ok()
200    }
201
202    /// Get pricing for a specific listing. Returns full `Result`.
203    pub async fn try_fab_listing_prices(
204        &self,
205        uid: &str,
206    ) -> Result<Vec<fab_search::FabPriceInfo>, EpicAPIError> {
207        self.egs.fab_listing_prices(uid).await
208    }
209
210    /// Get reviews for a listing. Returns `None` on error.
211    pub async fn fab_listing_reviews(
212        &self,
213        uid: &str,
214        sort_by: Option<&str>,
215        cursor: Option<&str>,
216    ) -> Option<fab_search::FabReviewsResponse> {
217        self.egs
218            .fab_listing_reviews(uid, sort_by, cursor)
219            .await
220            .ok()
221    }
222
223    /// Get reviews for a listing. Returns full `Result`.
224    pub async fn try_fab_listing_reviews(
225        &self,
226        uid: &str,
227        sort_by: Option<&str>,
228        cursor: Option<&str>,
229    ) -> Result<fab_search::FabReviewsResponse, EpicAPIError> {
230        self.egs.fab_listing_reviews(uid, sort_by, cursor).await
231    }
232
233    // ── Fab Taxonomy ──
234
235    /// Fetch available license types. Returns `None` on error.
236    pub async fn fab_licenses(&self) -> Option<Vec<fab_taxonomy::FabLicenseType>> {
237        self.egs.fab_licenses().await.ok()
238    }
239
240    /// Fetch available license types. Returns full `Result`.
241    pub async fn try_fab_licenses(
242        &self,
243    ) -> Result<Vec<fab_taxonomy::FabLicenseType>, EpicAPIError> {
244        self.egs.fab_licenses().await
245    }
246
247    /// Fetch asset format groups. Returns `None` on error.
248    pub async fn fab_format_groups(&self) -> Option<Vec<fab_taxonomy::FabFormatGroup>> {
249        self.egs.fab_format_groups().await.ok()
250    }
251
252    /// Fetch asset format groups. Returns full `Result`.
253    pub async fn try_fab_format_groups(
254        &self,
255    ) -> Result<Vec<fab_taxonomy::FabFormatGroup>, EpicAPIError> {
256        self.egs.fab_format_groups().await
257    }
258
259    /// Fetch tag groups with nested tags. Returns `None` on error.
260    pub async fn fab_tag_groups(&self) -> Option<Vec<fab_taxonomy::FabTagGroup>> {
261        self.egs.fab_tag_groups().await.ok()
262    }
263
264    /// Fetch tag groups with nested tags. Returns full `Result`.
265    pub async fn try_fab_tag_groups(&self) -> Result<Vec<fab_taxonomy::FabTagGroup>, EpicAPIError> {
266        self.egs.fab_tag_groups().await
267    }
268
269    /// Fetch available UE versions. Returns `None` on error.
270    pub async fn fab_ue_versions(&self) -> Option<Vec<String>> {
271        self.egs.fab_ue_versions().await.ok()
272    }
273
274    /// Fetch available UE versions. Returns full `Result`.
275    pub async fn try_fab_ue_versions(&self) -> Result<Vec<String>, EpicAPIError> {
276        self.egs.fab_ue_versions().await
277    }
278
279    /// Fetch channel info by slug. Returns `None` on error.
280    pub async fn fab_channel(&self, slug: &str) -> Option<fab_taxonomy::FabChannel> {
281        self.egs.fab_channel(slug).await.ok()
282    }
283
284    /// Fetch channel info by slug. Returns full `Result`.
285    pub async fn try_fab_channel(
286        &self,
287        slug: &str,
288    ) -> Result<fab_taxonomy::FabChannel, EpicAPIError> {
289        self.egs.fab_channel(slug).await
290    }
291
292    // ── Fab Library Entitlements ──
293
294    /// Search library entitlements. Returns `None` on error.
295    pub async fn fab_library_entitlements(
296        &self,
297        params: &fab_entitlement::FabEntitlementSearchParams,
298    ) -> Option<fab_entitlement::FabEntitlementResults> {
299        self.egs.fab_library_entitlements(params).await.ok()
300    }
301
302    /// Search library entitlements. Returns full `Result`.
303    pub async fn try_fab_library_entitlements(
304        &self,
305        params: &fab_entitlement::FabEntitlementSearchParams,
306    ) -> Result<fab_entitlement::FabEntitlementResults, EpicAPIError> {
307        self.egs.fab_library_entitlements(params).await
308    }
309
310    // ── Fab Session ──
311
312    /// Initialize Fab CSRF token. Sets cookies on the shared HTTP client.
313    pub async fn fab_csrf(&self) -> Result<(), EpicAPIError> {
314        self.egs.fab_csrf().await
315    }
316
317    /// Fetch Fab user context. Returns `None` on error.
318    pub async fn fab_user_context(&self) -> Option<fab_search::FabUserContext> {
319        self.egs.fab_user_context().await.ok()
320    }
321
322    /// Fetch Fab user context. Returns full `Result`.
323    pub async fn try_fab_user_context(&self) -> Result<fab_search::FabUserContext, EpicAPIError> {
324        self.egs.fab_user_context().await
325    }
326
327    /// Add a free listing to the user's library. Returns `Ok(())` on success.
328    pub async fn fab_add_to_library(&self, listing_uid: &str) -> Result<(), EpicAPIError> {
329        self.egs.fab_add_to_library(listing_uid).await
330    }
331
332    /// Fetch all available asset formats for a listing. Returns `None` on error.
333    pub async fn fab_listing_formats(
334        &self,
335        listing_uid: &str,
336    ) -> Option<Vec<fab_search::FabListingFormat>> {
337        self.egs.fab_listing_formats(listing_uid).await.ok()
338    }
339
340    /// Fetch all available asset formats. Returns full `Result`.
341    pub async fn try_fab_listing_formats(
342        &self,
343        listing_uid: &str,
344    ) -> Result<Vec<fab_search::FabListingFormat>, EpicAPIError> {
345        self.egs.fab_listing_formats(listing_uid).await
346    }
347}