fortnite_api/
lib.rs

1#![deny(warnings)]
2#![deny(unused)]
3#![deny(clippy::expect_used)]
4#![deny(clippy::get_unwrap)]
5#![deny(clippy::exit)]
6#![deny(clippy::indexing_slicing)]
7#![deny(clippy::panic)]
8#![deny(clippy::panic_in_result_fn)]
9#![deny(clippy::unreachable)]
10#![deny(clippy::print_stdout)]
11#![allow(clippy::upper_case_acronyms)]
12
13//! # Fortnite API
14//! This crate is a wrapper for the Fortnite API.
15//!
16//! ## Usage
17//!
18//! ```rust no_run
19//! #[tokio::main]
20//! async fn main() {
21//!     let http_client = reqwest::Client::new();
22//!
23//!     let result = fortnite_api::get_news_v2(&http_client, None).await;
24//!     println!("Result: {result:#?}");
25//!     assert!(result.is_ok());
26//! }
27//! ```
28//!
29//! ## Endpoints
30//!
31//! | Endpoint | Function | Result Type |
32//! | --- | --- | --- |
33//! | AES V2 | [`get_aes_keys_v2`] | [`AesV2`] |
34//! | Banners V1 | [`get_banners_v1`] | [`BannersV1`] |
35//! | Banners Colors V1 | [`get_banners_colors_v1`] | [`BannersColorsV1`] |
36//! | Cosmetics V2 | [`get_cosmetics_v2`] | [`CosmeticsV2`] |
37//! | Cosmetics New V2 | [`get_cosmetics_new_v2`] | [`CosmeticsNewV2`] |
38//! | Cosmetic By ID V2 | [`get_cosmetic_by_id_v2`] | [`CosmeticV2`] |
39//! | Creator Code V2 | [`get_creatorcode_v2`] | [`CreatorCodeV2`] |
40//! | Map V1 | [`get_map_v1`] | [`MapV1`] |
41//! | News V2 | [`get_news_v2`] | [`NewsV2`] |
42//! | News Gamemode V2 | [`get_news_br_v2`] [`get_news_stw_v2`] [`get_news_creative_v2`] | [`News`] |
43//! | Playlists V1 | [`get_playlists_v1`] | [`PlaylistsV1`] |
44//! | Playlists By ID V1 | [`get_playlist_by_id_v1`] | [`PlaylistV1`] |
45//! | Shop BR V2 | [`get_shop_br_v2`] [`get_shop_combined_v2`] | [`ShopV2`] |
46//! | Stats V2 | [`get_stats_v2`] [`get_stats_by_account_id_v2`] | [`StatsV2`] |
47
48use std::collections::HashMap;
49use std::str::FromStr;
50
51use reqwest::Url;
52
53use crate::response_types::aes::{AesKeyFormat, AesV2};
54use crate::response_types::banners::{BannersColorsV1, BannersV1};
55use crate::response_types::cosmetics::{CosmeticV2, CosmeticsNewV2, CosmeticsV2};
56use crate::response_types::creatorcode::CreatorCodeV2;
57use crate::response_types::map::MapV1;
58use crate::response_types::news::{News, NewsV2};
59use crate::response_types::playlists::{PlaylistV1, PlaylistsV1};
60use crate::response_types::shop::ShopV2;
61use crate::response_types::stats::{StatsAccountType, StatsImage, StatsTimeWindow, StatsV2};
62use crate::utils::fetch::fetch_endpoint;
63
64pub mod response_types;
65pub mod utils;
66
67pub async fn get_aes_keys_v2(
68    http_client: &reqwest::Client,
69    key_format: Option<AesKeyFormat>,
70) -> reqwest::Result<AesV2> {
71    //! Get the current AES keys.
72    //!
73    //! ## Parameters
74    //!
75    //! - `http_client`: The reqwest client.
76    //! - `key_format`: The format of the AES keys. Can be `None`, `Some(AesKeyFormat::Hex)`, or `Some(AesKeyFormat::Base64)`.
77    //!
78    //! ## Returns
79    //!
80    //! The current AES keys.
81    //!
82    //! ## Example
83    //!
84    //! ```rust
85    //! use fortnite_api::response_types::aes::AesKeyFormat;
86    //!
87    //! #[tokio::main]
88    //! async fn main() {
89    //!     let http_client = reqwest::Client::new();
90    //!
91    //!     let result = fortnite_api::get_aes_keys_v2(&http_client, Some(AesKeyFormat::Hex)).await;
92    //!     println!("Result: {result:#?}");
93    //!     assert!(result.is_ok());
94    //! }
95    //! ```
96    let mut url = Url::from_str("https://fortnite-api.com/v2/aes").unwrap();
97    if let Some(key_format) = key_format {
98        url.query_pairs_mut()
99            .append_pair("keyFormat", &key_format.to_string());
100    }
101
102    fetch_endpoint(http_client, url, "GET", "", &HashMap::new()).await
103}
104
105pub async fn get_banners_v1(
106    http_client: &reqwest::Client,
107    language: Option<&str>,
108) -> reqwest::Result<BannersV1> {
109    //! Get the banners.
110    //!
111    //! ## Parameters
112    //!
113    //! - `http_client`: The reqwest client.
114    //! - `language`: The language of the banners. Can be `None` or a language code.
115    //!
116    //! ## Returns
117    //!
118    //! The banners.
119    //!
120    //! ## Example
121    //!
122    //! ```rust
123    //! #[tokio::main]
124    //! async fn main() {
125    //!     let http_client = reqwest::Client::new();
126    //!
127    //!     let result = fortnite_api::get_banners_v1(&http_client, None).await;
128    //!     println!("Result: {result:#?}");
129    //!     assert!(result.is_ok());
130    //! }
131    //! ```
132    let mut url = Url::from_str("https://fortnite-api.com/v1/banners").unwrap();
133    if let Some(language) = language {
134        url.query_pairs_mut().append_pair("language", language);
135    }
136
137    fetch_endpoint(http_client, url, "GET", "", &HashMap::new()).await
138}
139
140pub async fn get_banners_colors_v1(
141    http_client: &reqwest::Client,
142) -> reqwest::Result<BannersColorsV1> {
143    //! Get the banner colors.
144    //!
145    //! ## Parameters
146    //!
147    //! - `http_client`: The reqwest client.
148    //!
149    //! ## Returns
150    //!
151    //! The banner colors.
152    //!
153    //! ## Example
154    //!
155    //! ```rust
156    //! #[tokio::main]
157    //! async fn main() {
158    //!     let http_client = reqwest::Client::new();
159    //!
160    //!     let result = fortnite_api::get_banners_colors_v1(&http_client).await;
161    //!     println!("Result: {result:#?}");
162    //!     assert!(result.is_ok());
163    //! }
164    //! ```
165    let url = Url::from_str("https://fortnite-api.com/v1/banners/colors").unwrap();
166
167    fetch_endpoint(http_client, url, "GET", "", &HashMap::new()).await
168}
169
170pub async fn get_cosmetics_v2(
171    http_client: &reqwest::Client,
172    language: Option<&str>,
173) -> reqwest::Result<CosmeticsV2> {
174    //! Get the cosmetics.
175    //!
176    //! ## Parameters
177    //!
178    //! - `http_client`: The reqwest client.
179    //! - `language`: The language of the cosmetics. Can be `None` or a language code.
180    //!
181    //! ## Returns
182    //!
183    //! The cosmetics.
184    //!
185    //! ## Example
186    //!
187    //! ```rust
188    //! #[tokio::main]
189    //! async fn main() {
190    //!     let http_client = reqwest::Client::new();
191    //!
192    //!     let result = fortnite_api::get_cosmetics_v2(&http_client, None).await;
193    //!     assert!(result.is_ok());
194    //! }
195    //! ```
196    let mut url = Url::from_str("https://fortnite-api.com/v2/cosmetics/br").unwrap();
197    if let Some(language) = language {
198        url.query_pairs_mut().append_pair("language", language);
199    }
200
201    fetch_endpoint(http_client, url, "GET", "", &HashMap::new()).await
202}
203
204pub async fn get_cosmetics_new_v2(
205    http_client: &reqwest::Client,
206    language: Option<&str>,
207) -> reqwest::Result<CosmeticsNewV2> {
208    //! Get the new cosmetics.
209    //!
210    //! ## Parameters
211    //!
212    //! - `http_client`: The reqwest client.
213    //! - `language`: The language of the cosmetics. Can be `None` or a language code.
214    //!
215    //! ## Returns
216    //!
217    //! The new cosmetics.
218    //!
219    //! ## Example
220    //!
221    //! ```rust
222    //! #[tokio::main]
223    //! async fn main() {
224    //!     let http_client = reqwest::Client::new();
225    //!
226    //!     let result = fortnite_api::get_cosmetics_new_v2(&http_client, None).await;
227    //!     assert!(result.is_ok());
228    //! }
229    //! ```
230    let mut url = Url::from_str("https://fortnite-api.com/v2/cosmetics/br/new").unwrap();
231    if let Some(language) = language {
232        url.query_pairs_mut().append_pair("language", language);
233    }
234
235    fetch_endpoint(http_client, url, "GET", "", &HashMap::new()).await
236}
237
238pub async fn get_cosmetic_by_id_v2(
239    http_client: &reqwest::Client,
240    cosmetic_id: &str,
241    language: Option<&str>,
242) -> reqwest::Result<CosmeticV2> {
243    //! Get the cosmetic by ID.
244    //!
245    //! ## Parameters
246    //!
247    //! - `http_client`: The reqwest client.
248    //! - `cosmetic_id`: The ID of the cosmetic.
249    //! - `language`: The language of the cosmetic. Can be `None` or a language code.
250    //!
251    //! ## Returns
252    //!
253    //! The cosmetic by ID.
254    //!
255    //! ## Example
256    //!
257    //! ```rust
258    //! #[tokio::main]
259    //! async fn main() {
260    //!     let http_client = reqwest::Client::new();
261    //!
262    //!     let result = fortnite_api::get_cosmetics_new_v2(&http_client, None).await;
263    //!     assert!(result.is_ok());
264    //!
265    //!     let cosmetic_id = result.unwrap().items.first().unwrap().id.clone();
266    //!     let result = fortnite_api::get_cosmetic_by_id_v2(&http_client, &cosmetic_id, None).await;
267    //!     println!("Result: {result:#?}");
268    //!     assert!(result.is_ok());
269    //! }
270    //! ```
271    let mut url =
272        Url::from_str(format!("https://fortnite-api.com/v2/cosmetics/br/{cosmetic_id}").as_str())
273            .unwrap();
274    if let Some(language) = language {
275        url.query_pairs_mut().append_pair("language", language);
276    }
277
278    fetch_endpoint(http_client, url, "GET", "", &HashMap::new()).await
279}
280
281pub async fn get_creatorcode_v2(
282    http_client: &reqwest::Client,
283    name: &str,
284) -> reqwest::Result<CreatorCodeV2> {
285    //! Get the creator code.
286    //!
287    //! ## Parameters
288    //!
289    //! - `http_client`: The reqwest client.
290    //! - `name`: The name of the creator code.
291    //!
292    //! ## Returns
293    //!
294    //! The creator code.
295    //!
296    //! ## Example
297    //!
298    //! ```rust
299    //! #[tokio::main]
300    //! async fn main() {
301    //!     let http_client = reqwest::Client::new();
302    //!
303    //!     let result = fortnite_api::get_creatorcode_v2(&http_client, "trymacs").await;
304    //!     println!("Result: {result:#?}");
305    //!     assert!(result.is_ok());
306    //! }
307    //! ```
308    let mut url = Url::from_str("https://fortnite-api.com/v2/creatorcode").unwrap();
309    url.query_pairs_mut().append_pair("name", name);
310
311    fetch_endpoint(http_client, url, "GET", "", &HashMap::new()).await
312}
313
314pub async fn get_map_v1(
315    http_client: &reqwest::Client,
316    language: Option<&str>,
317) -> reqwest::Result<MapV1> {
318    //! Get the map.
319    //!
320    //! ## Parameters
321    //!
322    //! - `http_client`: The reqwest client.
323    //! - `language`: The language of the map. Can be `None` or a language code.
324    //!
325    //! ## Returns
326    //!
327    //! The map.
328    //!
329    //! ## Example
330    //!
331    //! ```rust
332    //! #[tokio::main]
333    //! async fn main() {
334    //!     let http_client = reqwest::Client::new();
335    //!
336    //!     let result = fortnite_api::get_map_v1(&http_client, None).await;
337    //!     println!("Result: {result:#?}");
338    //!     assert!(result.is_ok());
339    //! }
340    //! ```
341    let mut url = Url::from_str("https://fortnite-api.com/v1/map").unwrap();
342    if let Some(language) = language {
343        url.query_pairs_mut().append_pair("language", language);
344    }
345
346    fetch_endpoint(http_client, url, "GET", "", &HashMap::new()).await
347}
348
349pub async fn get_news_v2(
350    http_client: &reqwest::Client,
351    language: Option<&str>,
352) -> reqwest::Result<NewsV2> {
353    //! Get the news.
354    //!
355    //! ## Parameters
356    //!
357    //! - `http_client`: The reqwest client.
358    //! - `language`: The language of the news. Can be `None` or a language code.
359    //!
360    //! ## Returns
361    //!
362    //! The news.
363    //!
364    //! ## Example
365    //!
366    //! ```rust
367    //! #[tokio::main]
368    //! async fn main() {
369    //!     let http_client = reqwest::Client::new();
370    //!
371    //!     let result = fortnite_api::get_news_v2(&http_client, None).await;
372    //!     println!("Result: {result:#?}");
373    //! }
374    //! ```
375    let mut url = Url::from_str("https://fortnite-api.com/v2/news").unwrap();
376    if let Some(language) = language {
377        url.query_pairs_mut().append_pair("language", language);
378    }
379
380    fetch_endpoint(http_client, url, "GET", "", &HashMap::new()).await
381}
382
383pub async fn get_news_br_v2(
384    http_client: &reqwest::Client,
385    language: Option<&str>,
386) -> reqwest::Result<News> {
387    //! Get the battle royale news.
388    //!
389    //! ## Parameters
390    //!
391    //! - `http_client`: The reqwest client.
392    //! - `language`: The language of the news. Can be `None` or a language code.
393    //!
394    //! ## Returns
395    //!
396    //! The battle royale news.
397    //!
398    //! ## Example
399    //!
400    //! ```rust
401    //! #[tokio::main]
402    //! async fn main() {
403    //!     let http_client = reqwest::Client::new();
404    //!
405    //!     let result = fortnite_api::get_news_br_v2(&http_client, None).await;
406    //!     println!("Result: {result:#?}");
407    //! }
408    //! ```
409    let mut url = Url::from_str("https://fortnite-api.com/v2/news/br").unwrap();
410    if let Some(language) = language {
411        url.query_pairs_mut().append_pair("language", language);
412    }
413
414    fetch_endpoint(http_client, url, "GET", "", &HashMap::new()).await
415}
416
417pub async fn get_news_stw_v2(
418    http_client: &reqwest::Client,
419    language: Option<&str>,
420) -> reqwest::Result<News> {
421    //! Get the save the world news.
422    //!
423    //! ## Parameters
424    //!
425    //! - `http_client`: The reqwest client.
426    //! - `language`: The language of the news. Can be `None` or a language code.
427    //!
428    //! ## Returns
429    //!
430    //! The save the world news.
431    //!
432    //! ## Example
433    //!
434    //! ```rust
435    //! #[tokio::main]
436    //! async fn main() {
437    //!     let http_client = reqwest::Client::new();
438    //!
439    //!     let result = fortnite_api::get_news_stw_v2(&http_client, None).await;
440    //!     println!("Result: {result:#?}");
441    //! }
442    //! ```
443    let mut url = Url::from_str("https://fortnite-api.com/v2/news/stw").unwrap();
444    if let Some(language) = language {
445        url.query_pairs_mut().append_pair("language", language);
446    }
447
448    fetch_endpoint(http_client, url, "GET", "", &HashMap::new()).await
449}
450
451pub async fn get_news_creative_v2(
452    http_client: &reqwest::Client,
453    language: Option<&str>,
454) -> reqwest::Result<News> {
455    //! Get the creative news.
456    //!
457    //! ## Parameters
458    //!
459    //! - `http_client`: The reqwest client.
460    //! - `language`: The language of the news. Can be `None` or a language code.
461    //!
462    //! ## Returns
463    //!
464    //! The creative news.
465    //!
466    //! ## Example
467    //!
468    //! ```rust
469    //! #[tokio::main]
470    //! async fn main() {
471    //!     let http_client = reqwest::Client::new();
472    //!
473    //!     let result = fortnite_api::get_news_creative_v2(&http_client, None).await;
474    //!     println!("Result: {result:#?}");
475    //! }
476    //! ```
477    let mut url = Url::from_str("https://fortnite-api.com/v2/news/creative").unwrap();
478    if let Some(language) = language {
479        url.query_pairs_mut().append_pair("language", language);
480    }
481
482    fetch_endpoint(http_client, url, "GET", "", &HashMap::new()).await
483}
484
485pub async fn get_playlists_v1(
486    http_client: &reqwest::Client,
487    language: Option<&str>,
488) -> reqwest::Result<PlaylistsV1> {
489    //! Get the playlists.
490    //!
491    //! ## Parameters
492    //!
493    //! - `http_client`: The reqwest client.
494    //! - `language`: The language of the playlists. Can be `None` or a language code.
495    //!
496    //! ## Returns
497    //!
498    //! The playlists.
499    //!
500    //! ## Example
501    //!
502    //! ```rust
503    //! #[tokio::main]
504    //! async fn main() {
505    //!     let http_client = reqwest::Client::new();
506    //!
507    //!     let result = fortnite_api::get_playlists_v1(&http_client, None).await;
508    //!     println!("Result: {result:#?}");
509    //!     assert!(result.is_ok());
510    //! }
511    //! ```
512    let mut url = Url::from_str("https://fortnite-api.com/v1/playlists").unwrap();
513    if let Some(language) = language {
514        url.query_pairs_mut().append_pair("language", language);
515    }
516
517    fetch_endpoint(http_client, url, "GET", "", &HashMap::new()).await
518}
519
520pub async fn get_playlist_by_id_v1(
521    http_client: &reqwest::Client,
522    playlist_id: &str,
523    language: Option<&str>,
524) -> reqwest::Result<PlaylistV1> {
525    //! Get the playlist by ID.
526    //!
527    //! ## Parameters
528    //!
529    //! - `http_client`: The reqwest client.
530    //! - `language`: The language of the playlists. Can be `None` or a language code.
531    //!
532    //! ## Returns
533    //!
534    //! The playlist by ID.
535    //!
536    //! ## Example
537    //!
538    //! ```rust
539    //! #[tokio::main]
540    //! async fn main() {
541    //!     let http_client = reqwest::Client::new();
542    //!
543    //!     let result = fortnite_api::get_playlists_v1(&http_client, None).await;
544    //!     println!("Result: {result:#?}");
545    //!     assert!(result.is_ok());
546    //!
547    //!     let playlist_id = result.unwrap().first().unwrap().id.clone();
548    //!     let result = fortnite_api::get_playlist_by_id_v1(&http_client, &playlist_id, None).await;
549    //!     println!("Result: {result:#?}");
550    //! }
551    //! ```
552    let mut url =
553        Url::from_str(format!("https://fortnite-api.com/v1/playlists/{playlist_id}").as_str())
554            .unwrap();
555    if let Some(language) = language {
556        url.query_pairs_mut().append_pair("language", language);
557    }
558
559    fetch_endpoint(http_client, url, "GET", "", &HashMap::new()).await
560}
561
562pub async fn get_shop_br_v2(
563    http_client: &reqwest::Client,
564    language: Option<&str>,
565) -> reqwest::Result<ShopV2> {
566    //! Get the battle royale shop.
567    //!
568    //! ## Parameters
569    //!
570    //! - `http_client`: The reqwest client.
571    //! - `language`: The language of the shop. Can be `None` or a language code.
572    //!
573    //! ## Returns
574    //!
575    //! The battle royale shop.
576    //!
577    //! ## Example
578    //!
579    //! ```rust
580    //! #[tokio::main]
581    //! async fn main() {
582    //!     let http_client = reqwest::Client::new();
583    //!
584    //!     let result = fortnite_api::get_shop_br_v2(&http_client, None).await;
585    //!     println!("Result: {result:#?}");
586    //!     assert!(result.is_ok());
587    //! }
588    //! ```
589    let mut url = Url::from_str("https://fortnite-api.com/v2/shop/br").unwrap();
590    if let Some(language) = language {
591        url.query_pairs_mut().append_pair("language", language);
592    }
593
594    fetch_endpoint(http_client, url, "GET", "", &HashMap::new()).await
595}
596
597pub async fn get_shop_combined_v2(
598    http_client: &reqwest::Client,
599    language: Option<&str>,
600) -> reqwest::Result<ShopV2> {
601    //! Get the combined shop.
602    //!
603    //! ## Parameters
604    //!
605    //! - `http_client`: The reqwest client.
606    //! - `language`: The language of the shop. Can be `None` or a language code.
607    //!
608    //! ## Returns
609    //!
610    //! The combined shop.
611    //!
612    //! ## Example
613    //!
614    //! ```rust
615    //! #[tokio::main]
616    //! async fn main() {
617    //!     let http_client = reqwest::Client::new();
618    //!
619    //!     let result = fortnite_api::get_shop_combined_v2(&http_client, None).await;
620    //!     println!("Result: {result:#?}");
621    //!     assert!(result.is_ok());
622    //! }
623    //! ```
624    let mut url = Url::from_str("https://fortnite-api.com/v2/shop/br/combined").unwrap();
625    if let Some(language) = language {
626        url.query_pairs_mut().append_pair("language", language);
627    }
628
629    fetch_endpoint(http_client, url, "GET", "", &HashMap::new()).await
630}
631
632pub async fn get_stats_v2(
633    http_client: &reqwest::Client,
634    api_key: String,
635    name: &str,
636    account_type: Option<StatsAccountType>,
637    time_window: Option<StatsTimeWindow>,
638    image: Option<StatsImage>,
639) -> reqwest::Result<StatsV2> {
640    //! Get the player stats.
641    //!
642    //! ## Parameters
643    //!
644    //! - `http_client`: The reqwest client.
645    //! - `api_key`: Your Fortnite API key.
646    //! - `name`: The name of the player.
647    //! - `account_type`: The account type of the player. Can be `None` or [`StatsAccountType`].
648    //! - `time_window`: The time window of the stats. Can be `None` or [`StatsTimeWindow`].
649    //! - `image`: The image of the stats. Can be `None` or [`StatsImage`].
650    //! - `language`: The language of the shop. Can be `None` or a language code.
651    //!
652    //! ## Returns
653    //!
654    //! The player stats.
655    //!
656    //! ## Example
657    //!
658    //! ```rust,ignore
659    //! use fortnite_api::response_types::stats::{StatsAccountType, StatsImage, StatsTimeWindow};
660    //!
661    //! #[tokio::main]
662    //! async fn main() {
663    //!     dotenv::dotenv().ok();
664    //!     let http_client = reqwest::Client::new();
665    //!     let api_key = std::env::var("FORTNITE_API_KEY")
666    //!         .expect("Please set the FORTNITE_API_KEY environment variable");
667    //!
668    //!     let result =
669    //!         fortnite_api::get_stats_v2(&http_client, api_key.clone(), "Test", None, None, None).await;
670    //!     println!("Result: {result:#?}");
671    //!     assert!(result.is_ok());
672    //! }
673    //! ```
674    let mut url = Url::from_str("https://fortnite-api.com/v2/stats/br/v2").unwrap();
675    url.query_pairs_mut().append_pair("name", name);
676    if let Some(account_type) = account_type {
677        url.query_pairs_mut()
678            .append_pair("accountType", &account_type.to_string().to_lowercase());
679    }
680    if let Some(time_window) = time_window {
681        url.query_pairs_mut()
682            .append_pair("timeWindow", &time_window.to_string().to_lowercase());
683    }
684    if let Some(image) = image {
685        url.query_pairs_mut()
686            .append_pair("image", &image.to_string().to_lowercase());
687    }
688    let headers = [("Authorization".to_string(), api_key)]
689        .into_iter()
690        .collect();
691
692    fetch_endpoint(http_client, url, "GET", "", &headers).await
693}
694
695pub async fn get_stats_by_account_id_v2(
696    http_client: &reqwest::Client,
697    api_key: String,
698    account_id: &str,
699    time_window: Option<StatsTimeWindow>,
700    image: Option<StatsImage>,
701) -> reqwest::Result<StatsV2> {
702    //! Get the player stats by account ID.
703    //!
704    //! ## Parameters
705    //!
706    //! - `http_client`: The reqwest client.
707    //! - `api_key`: Your Fortnite API key.
708    //! - `account_id`: The account ID of the player.
709    //! - `time_window`: The time window of the stats. Can be `None` or [`StatsTimeWindow`].
710    //! - `image`: The image of the stats. Can be `None` or [`StatsImage`].
711    //!
712    //! ## Returns
713    //!
714    //! The player stats.
715    //!
716    //! ## Example
717    //!
718    //! ```rust,ignore
719    //! use fortnite_api::response_types::stats::{StatsAccountType, StatsImage, StatsTimeWindow};
720    //!
721    //! #[tokio::main]
722    //! async fn main() {
723    //!     dotenv::dotenv().ok();
724    //!     let http_client = reqwest::Client::new();
725    //!     let api_key = std::env::var("FORTNITE_API_KEY")
726    //!         .expect("Please set the FORTNITE_API_KEY environment variable");
727    //!
728    //!     let result = fortnite_api::get_stats_by_account_id_v2(
729    //!         &http_client,
730    //!         api_key.clone(),
731    //!         "3f20d6f579db4e7ba71d80fc18576db2",
732    //!         None,
733    //!         None,
734    //!     )
735    //!     .await;
736    //!     println!("Result: {result:#?}");
737    //!     assert!(result.is_ok());
738    //! }
739    //! ```
740    let mut url =
741        Url::from_str(format!("https://fortnite-api.com/v2/stats/br/v2/{account_id}").as_str())
742            .unwrap();
743    if let Some(time_window) = time_window {
744        url.query_pairs_mut()
745            .append_pair("timeWindow", &time_window.to_string().to_lowercase());
746    }
747    if let Some(image) = image {
748        url.query_pairs_mut()
749            .append_pair("image", &image.to_string().to_lowercase());
750    }
751    let headers = [("Authorization".to_string(), api_key)]
752        .into_iter()
753        .collect();
754
755    fetch_endpoint(http_client, url, "GET", "", &headers).await
756}