coc_rs/
lib.rs

1/// Base API wrapper
2pub mod api;
3
4/// API models
5mod models;
6pub use models::*;
7
8/// Clash of Stats API wrapper
9#[cfg(feature = "cos")]
10mod clash_of_stats;
11#[cfg(feature = "cos")]
12pub use clash_of_stats::*;
13#[cfg(feature = "cos")]
14mod cos_models;
15#[cfg(feature = "cos")]
16pub use cos_models::*;
17
18/// To structure a login
19pub mod credentials;
20
21/// Developer Site API wrapper
22mod dev;
23
24/// API + Clash of Stats Errors
25pub mod error;
26
27/// Events track changes in the API
28pub mod events;
29
30#[cfg(feature = "extra")]
31pub mod util;
32
33#[cfg(not(feature = "extra"))]
34mod util;
35
36#[macro_use]
37extern crate num_derive;
38
39#[cfg(test)]
40mod tests {
41    use std::{env, time::Instant};
42
43    use anyhow::{Context, Result};
44    use async_trait::async_trait;
45    use time::Month;
46
47    use crate::{
48        api::Client,
49        credentials::Credentials,
50        error::APIError,
51        events::{EventHandler, EventType, EventsListenerBuilder},
52        location::Local,
53        models::{clan, clan_search, leagues, location, paging, player, season},
54    };
55
56    static mut LOADED: bool = false;
57
58    lazy_static::lazy_static!(
59        pub static ref CLIENT: Client = Client::default();
60    );
61
62    /// Get an environment variable, returning an Err with a
63    /// nice error message mentioning the missing variable in case the value is not found.
64    fn required_env_var(key: &str) -> Result<String> {
65        env::var(key).with_context(|| format!("Missing environment variable {key}"))
66    }
67
68    async fn load_client() -> anyhow::Result<()> {
69        unsafe {
70            if !LOADED {
71                let credentials = Credentials::builder();
72                let credentials = required_env_var("emails")?
73                    .split(',')
74                    .map(std::string::ToString::to_string)
75                    .zip(
76                        required_env_var("passwords")?
77                            .split(',')
78                            .map(std::string::ToString::to_string),
79                    )
80                    .fold(credentials, |credentials, (email, password)| {
81                        credentials.add_credential(email, password)
82                    })
83                    .build();
84
85                CLIENT.load(credentials).await?;
86                LOADED = true;
87            }
88        }
89        Ok(())
90    }
91
92    #[test]
93    fn test_credentials() {
94        let credentials = Credentials::builder()
95            .add_credential("user1".to_owned(), "pass1".to_owned())
96            .add_credential("user2".to_owned(), "pass2".to_owned())
97            .build();
98        assert_eq!(credentials.0.len(), 2);
99        assert_eq!(credentials.0[0].email(), "user1");
100        assert_eq!(credentials.0[0].password(), "pass1");
101        assert_eq!(credentials.0[1].email(), "user2");
102        assert_eq!(credentials.0[1].password(), "pass2");
103    }
104
105    #[tokio::test]
106    async fn test_new_client() -> anyhow::Result<()> {
107        let credentials = Credentials::builder();
108        let credentials = required_env_var("emails")?
109            .split(',')
110            .map(std::string::ToString::to_string)
111            .zip(required_env_var("passwords")?.split(',').map(std::string::ToString::to_string))
112            .fold(credentials, |credentials, (email, password)| {
113                credentials.add_credential(email, password)
114            })
115            .build();
116
117        Client::new(credentials).await.map(|_| ())
118    }
119
120    #[tokio::test]
121    async fn test_reinit_client() -> anyhow::Result<()> {
122        let credentials = Credentials::builder();
123        let credentials = required_env_var("emails")?
124            .split(',')
125            .map(std::string::ToString::to_string)
126            .zip(required_env_var("passwords")?.split(',').map(std::string::ToString::to_string))
127            .fold(credentials, |credentials, (email, password)| {
128                credentials.add_credential(email, password)
129            })
130            .build();
131
132        let client = Client::new(credentials).await?;
133        client.reinit().await?;
134
135        Ok(())
136    }
137
138    #[tokio::test]
139    async fn test_get_clan_warlog() -> anyhow::Result<()> {
140        let now = Instant::now();
141
142        load_client().await.unwrap();
143
144        let clan_warlog = CLIENT.get_clan_warlog("2PJP2Q0PY").await?;
145        println!("Time elapsed! {:?}", now.elapsed());
146
147        println!("Clan warlog: {clan_warlog:?}");
148        Ok(())
149    }
150
151    #[tokio::test]
152    async fn test_get_clans() -> anyhow::Result<()> {
153        let now = Instant::now();
154
155        load_client().await?;
156
157        let clans = CLIENT
158            // .lock()
159            // .await
160            .get_clans(
161                clan_search::ClanSearchOptionsBuilder::new()
162                    .location_id(location::Local::UnitedStates)
163                    .max_members(5)
164                    .min_clan_level(20)
165                    .build(),
166            )
167            .await?;
168        println!("Time elapsed! {:?}", now.elapsed());
169
170        clans.items.iter().for_each(|clan| {
171            println!("{} - {}", clan.tag, clan.name);
172        });
173        Ok(())
174    }
175
176    #[tokio::test]
177    async fn test_get_current_war() -> anyhow::Result<()> {
178        let now = Instant::now();
179
180        load_client().await?;
181
182        let current_war = CLIENT.get_current_war("2L29GJ0G0").await?;
183        println!("Time elapsed! {:?}", now.elapsed());
184
185        println!("Current war: {current_war:?}");
186        Ok(())
187    }
188
189    #[tokio::test]
190    async fn test_get_clan() -> anyhow::Result<()> {
191        let now = Instant::now();
192
193        load_client().await?;
194
195        let clan = CLIENT.get_clan("90PU0RRG").await?;
196        println!("Time elapsed! {:?}", now.elapsed());
197
198        println!("Clan: {clan:?}");
199
200        Ok(())
201    }
202
203    #[tokio::test]
204    async fn test_get_clan_members() -> anyhow::Result<()> {
205        let now = Instant::now();
206
207        load_client().await?;
208
209        let clan_members = CLIENT.get_clan_members("2PP").await?;
210        println!("Time elapsed! {:?}", now.elapsed());
211
212        // retain clan members where role is Role::CoLeader and print each one when iterating, then collect
213        let co_leaders = clan_members
214            .items
215            .iter()
216            .filter(|member| member.role == clan::Role::CoLeader)
217            .collect::<Vec<_>>();
218        for member in &co_leaders {
219            println!("{} - {}", member.tag, member.name);
220        }
221        println!("And there are {} co-leaders", co_leaders.len());
222
223        Ok(())
224    }
225
226    #[tokio::test]
227    async fn test_get_clan_capital_raid_seasons() -> anyhow::Result<()> {
228        let now = Instant::now();
229
230        load_client().await?;
231
232        let clan_capital_raid_seasons = CLIENT.get_clan_capital_raid_seasons("2PP").await?;
233        println!("Time elapsed! {:?}", now.elapsed());
234
235        println!("Clan capital raid seasons: {clan_capital_raid_seasons:?}");
236        Ok(())
237    }
238
239    #[tokio::test]
240    async fn test_get_player() -> anyhow::Result<()> {
241        let now = Instant::now();
242
243        load_client().await?;
244
245        let player = CLIENT.get_player("2pp").await?;
246        println!("Time elapsed! {:?}", now.elapsed());
247
248        println!("Player: {player:?}");
249        #[cfg(feature = "extra")]
250        println!("Hero Pets: {:?}", player.hero_pets());
251        Ok(())
252    }
253
254    #[tokio::test]
255    async fn test_player_token() -> anyhow::Result<()> {
256        let now = Instant::now();
257
258        load_client().await?;
259
260        let verified = CLIENT.verify_player_token("CVJLQOLR", "").await?;
261
262        println!("Time elapsed! {:?}", now.elapsed());
263        println!("Verified: {verified:?}");
264
265        Ok(())
266    }
267
268    #[tokio::test]
269    async fn test_get_leagues() -> anyhow::Result<()> {
270        let now = Instant::now();
271
272        load_client().await?;
273
274        let leagues = CLIENT.get_leagues().await?;
275        println!("Time elapsed! {:?}", now.elapsed());
276
277        println!("Leagues: {leagues:?}");
278
279        Ok(())
280    }
281
282    #[tokio::test]
283    async fn test_get_league_season_rankings() -> anyhow::Result<()> {
284        let now = Instant::now();
285
286        println!("Logging in!");
287
288        load_client().await?;
289
290        println!("Logged in! {:?}", now.elapsed());
291
292        let league_season_rankings = CLIENT
293            // .lock()
294            // .await
295            .get_league_season_rankings(
296                leagues::LeagueKind::LegendLeague,
297                season::Season::builder().year(2015).month(Month::August).build(),
298                paging::Paging::builder().before(2).build(),
299            )
300            .await?;
301        println!("Time elapsed! {:?}", now.elapsed());
302
303        league_season_rankings.items.iter().for_each(|ranking| {
304            if let Some(clan) = ranking.clan.as_ref() {
305                println!(
306                    "We had a clan! {} - {} (Clan: {} - {})",
307                    ranking.tag, ranking.name, clan.tag, clan.name
308                );
309            }
310        });
311
312        Ok(())
313    }
314
315    #[tokio::test]
316    async fn test_get_league() -> anyhow::Result<()> {
317        let now = Instant::now();
318
319        load_client().await?;
320
321        let league = CLIENT.get_league(leagues::LeagueKind::LegendLeague).await?;
322        println!("Time elapsed! {:?}", now.elapsed());
323
324        println!("League: {league:?}");
325
326        Ok(())
327    }
328
329    #[tokio::test]
330    async fn test_get_league_seasons() -> anyhow::Result<()> {
331        let now = Instant::now();
332
333        load_client().await?;
334
335        let league_seasons = CLIENT.get_league_seasons(leagues::LeagueKind::LegendLeague).await?;
336        println!("Time elapsed! {:?}", now.elapsed());
337
338        league_seasons.items.iter().for_each(|season| {
339            println!("Season: {season}");
340        });
341
342        Ok(())
343    }
344
345    #[tokio::test]
346    async fn test_get_war_league() -> anyhow::Result<()> {
347        let now = Instant::now();
348
349        load_client().await?;
350
351        let war_league = CLIENT.get_war_league(leagues::WarLeagueKind::ChampionLeagueI).await?;
352        println!("Time elapsed! {:?}", now.elapsed());
353
354        println!("War league: {war_league:?}");
355
356        Ok(())
357    }
358
359    #[tokio::test]
360    async fn test_get_war_leagues() -> anyhow::Result<()> {
361        let now = Instant::now();
362
363        load_client().await?;
364
365        let war_leagues = CLIENT.get_war_leagues().await?;
366        println!("Time elapsed! {:?}", now.elapsed());
367
368        println!("War leagues: {war_leagues:?}");
369
370        Ok(())
371    }
372
373    #[tokio::test]
374    async fn test_get_clan_rankings() -> anyhow::Result<()> {
375        let now = Instant::now();
376
377        load_client().await?;
378
379        let mut clan_rankings = CLIENT.get_clan_rankings(location::Local::UnitedStates).await?;
380        println!("Time elapsed! {:?}", now.elapsed());
381
382        clan_rankings.items.sort_by(|a, b| a.clan_level.cmp(&b.clan_level));
383        for c in clan_rankings.items.iter().rev().take(100) {
384            println!("{:>3}. {:>9} - {:>15} ({})", c.rank, c.tag, c.name, c.clan_level);
385        }
386
387        Ok(())
388    }
389
390    #[tokio::test]
391    async fn test_get_player_rankings() -> anyhow::Result<()> {
392        let now = Instant::now();
393
394        load_client().await?;
395
396        let player_rankings = CLIENT.get_player_rankings(location::Local::UnitedStates).await?;
397        println!("Time elapsed! {:?}", now.elapsed());
398
399        for p in player_rankings
400            .items
401            .iter()
402            .filter(|player| player.clan.is_some() && player.trophies > 5800)
403            .take(100)
404        {
405            println!(
406                "{:>3}. {:>9} - {:>15} ({} - {})",
407                p.rank,
408                p.tag,
409                p.name,
410                p.clan.as_ref().unwrap().tag,
411                p.clan.as_ref().unwrap().name,
412            );
413        }
414
415        Ok(())
416    }
417
418    #[tokio::test]
419    async fn test_get_versus_clan_rankings() -> anyhow::Result<()> {
420        let now = Instant::now();
421
422        load_client().await?;
423
424        let mut versus_clan_rankings =
425            CLIENT.get_versus_clan_rankings(location::Local::UnitedStates).await?;
426        println!("Time elapsed! {:?}", now.elapsed());
427
428        versus_clan_rankings.items.sort_by(|a, b| a.clan_level.cmp(&b.clan_level));
429        for c in versus_clan_rankings.items.iter().rev().take(100) {
430            println!("{:>3}. {:>9} - {:>15} ({})", c.rank, c.tag, c.name, c.clan_level);
431        }
432
433        Ok(())
434    }
435
436    #[tokio::test]
437    async fn test_get_versus_player_rankings() -> anyhow::Result<()> {
438        let now = Instant::now();
439
440        load_client().await?;
441
442        let mut versus_player_rankings =
443            CLIENT.get_versus_player_rankings(location::Local::UnitedStates).await?;
444        println!("Time elapsed! {:?}", now.elapsed());
445
446        versus_player_rankings.items.sort_by(|a, b| a.exp_level.cmp(&b.exp_level));
447        for c in versus_player_rankings.items.iter().rev().take(100) {
448            println!("{:>3}. {:>9} - {:>15} ({})", c.rank, c.tag, c.name, c.exp_level);
449        }
450
451        Ok(())
452    }
453
454    #[tokio::test]
455    async fn test_get_locations() -> anyhow::Result<()> {
456        let now = Instant::now();
457
458        load_client().await?;
459
460        let locations = CLIENT.get_locations().await?;
461        println!("Time elapsed! {:?}", now.elapsed());
462
463        println!("Locations: {locations:?}");
464
465        Ok(())
466    }
467
468    #[tokio::test]
469    async fn test_get_location() -> anyhow::Result<()> {
470        let now = Instant::now();
471
472        load_client().await?;
473
474        let location = CLIENT.get_location(location::Local::UnitedStates).await?;
475        println!("Time elapsed! {:?}", now.elapsed());
476
477        println!("Location: {location:?}");
478
479        Ok(())
480    }
481
482    #[tokio::test]
483    async fn test_get_goldpass() -> anyhow::Result<()> {
484        let now = Instant::now();
485
486        load_client().await?;
487
488        let goldpass = CLIENT.get_goldpass().await?;
489        println!("Time elapsed! {:?}", now.elapsed());
490
491        println!("Goldpass Start: {}", goldpass.start_time());
492        println!("Goldpass End: {}", goldpass.end_time());
493
494        Ok(())
495    }
496
497    #[tokio::test]
498    async fn test_get_player_labels() -> anyhow::Result<()> {
499        let now = Instant::now();
500
501        load_client().await?;
502
503        let player_labels = CLIENT.get_player_labels().await?;
504        println!("Time elapsed! {:?}", now.elapsed());
505        println!("Player Labels: {player_labels:?}");
506
507        Ok(())
508    }
509
510    #[tokio::test]
511    async fn test_get_clan_labels() -> anyhow::Result<()> {
512        let now = Instant::now();
513
514        load_client().await?;
515
516        let player_label = CLIENT.get_clan_labels().await?;
517        println!("Time elapsed! {:?}", now.elapsed());
518
519        println!("Player Label: {player_label:?}");
520
521        Ok(())
522    }
523
524    #[tokio::test]
525    #[cfg(feature = "tracing")]
526    async fn test_delete_and_readd_keys() -> anyhow::Result<()> {
527        load_client().await?;
528
529        CLIENT.debug_keys();
530
531        Ok(())
532    }
533
534    #[test]
535    fn test_url() {
536        let tag = "2PP";
537        let encoded = urlencoding::encode(tag);
538        println!("{encoded}");
539    }
540    #[cfg(feature = "extra")]
541    #[tokio::test]
542    async fn test_1000_player_ids() -> anyhow::Result<()> {
543        use std::sync::Arc;
544
545        use crate::util::{LogicLong, HASH_TAG_CODE_GENERATOR};
546
547        load_client().await?;
548
549        // hold the lock for the entire test so it's not dropped and another test picks it up
550
551        let throttle_counter = Arc::new(tokio::sync::Mutex::new(0));
552
553        let now = Instant::now();
554
555        let tasks = (0..2000)
556            .map(|_| {
557                let logic_long = LogicLong::random(100);
558                let client = CLIENT.clone();
559                let cloned_throttle_counter = throttle_counter.clone();
560                async move {
561                    loop {
562                        match client.get_player(&HASH_TAG_CODE_GENERATOR.to_code(logic_long)).await
563                        {
564                            Ok(_) => break,
565                            Err(e) => match e {
566                                APIError::NotFound => break,
567                                APIError::RequestThrottled => {
568                                    *cloned_throttle_counter.lock().await += 1
569                                }
570                                _ => {
571                                    println!("Error: {e:?}");
572                                    break;
573                                }
574                            },
575                        }
576                    }
577                }
578            })
579            .collect::<Vec<_>>();
580
581        futures::future::join_all(tasks).await;
582
583        println!("Time elapsed! {:?}", now.elapsed());
584        println!("Throttle counter: {throttle_counter:?}");
585
586        Ok(())
587    }
588
589    #[tokio::test]
590    async fn test_event() -> anyhow::Result<()> {
591        struct S;
592
593        #[async_trait]
594        impl EventHandler for S {
595            async fn player(&self, old_player: Option<player::Player>, new_player: player::Player) {
596                println!(
597                    "From {} to {}",
598                    {
599                        if let Some(old_player) = old_player {
600                            old_player.tag
601                        } else {
602                            String::new()
603                        }
604                    },
605                    new_player.tag
606                );
607            }
608
609            async fn on_error(&self, error: APIError, tag: String, event_type: EventType) {
610                println!("Houston, we have a problem! {error} with {tag} @ {event_type}");
611            }
612        }
613
614        load_client().await?;
615
616        let task = async move {
617            let events_listener = EventsListenerBuilder::new(CLIENT.clone())
618                .add_player("2PP")
619                .add_clans(vec!["2PP"])
620                .build(S);
621            events_listener.start(Some(std::time::Duration::from_secs(5))).await
622        };
623
624        match task.await {
625            Ok(_) => println!("Done running task!"),
626            Err(e) => println!("Error running task: {e}"),
627        }
628
629        Ok(())
630    }
631
632    #[test]
633    fn test_primitive_to_local() {
634        let local = Local::from_i32(32_000_249);
635        assert_eq!(local, Some(Local::UnitedStates));
636    }
637
638    #[cfg(feature = "cos")]
639    #[cfg(test)]
640    mod tests_cos {
641        use std::{env, time::Instant};
642
643        use crate::{cos_options, credentials::Credentials, error::APIError, location::Local};
644
645        #[tokio::test]
646        async fn test_cos_login() -> Result<(), APIError> {
647            let now = Instant::now();
648            let credentials = Credentials::builder()
649                .add_credential(env::var("cosemail").unwrap(), env::var("cospassword").unwrap())
650                .build();
651            super::CLIENT.cos_login(&credentials).await?;
652
653            println!("Time elapsed! {:?}", now.elapsed());
654
655            Ok(())
656        }
657
658        #[tokio::test]
659        async fn test_cos_get_player() -> Result<(), APIError> {
660            let now = Instant::now();
661
662            let cos_player = super::CLIENT.cos_get_player("2PP").await?;
663
664            println!("{cos_player:?}");
665            println!("Time elapsed! {:?}", now.elapsed());
666
667            Ok(())
668        }
669
670        #[tokio::test]
671        async fn test_cos_get_player_history() -> Result<(), APIError> {
672            let now = Instant::now();
673
674            let cos_player_history = super::CLIENT.cos_get_player_history("2PP").await?;
675            println!("{cos_player_history:?}");
676            println!("Time elapsed! {:?}", now.elapsed());
677
678            Ok(())
679        }
680
681        #[tokio::test]
682        async fn test_cos_get_clan() -> Result<(), APIError> {
683            let now = Instant::now();
684
685            let cos_clan = super::CLIENT.cos_get_clan("2PP").await?;
686            println!("{cos_clan:?}");
687            println!("Time elapsed! {:?}", now.elapsed());
688
689            Ok(())
690        }
691
692        #[tokio::test]
693        async fn test_cos_get_clan_past_members() -> Result<(), APIError> {
694            let now = Instant::now();
695
696            let cos_clan_history = super::CLIENT.cos_get_clan_past_members("#2PP").await?;
697            println!("{cos_clan_history:?}");
698            println!("Time elapsed! {:?}", now.elapsed());
699
700            Ok(())
701        }
702
703        #[tokio::test]
704        async fn test_cos_get_war_wins_leaderboard() -> Result<(), APIError> {
705            let now = Instant::now();
706
707            let cos_clan_history = super::CLIENT
708                .cos_get_war_wins_leaderboard(
709                    cos_options::Options::builder().location(Local::None).page(1).build(),
710                )
711                .await?;
712            println!("{cos_clan_history:?}");
713            println!("Time elapsed! {:?}", now.elapsed());
714
715            Ok(())
716        }
717
718        #[tokio::test]
719        async fn test_cos_get_war_win_streak_leaderboard() -> Result<(), APIError> {
720            let now = Instant::now();
721
722            let cos_clan_history = super::CLIENT
723                .cos_get_war_win_streak_leaderboard(
724                    cos_options::Options::builder().location(Local::None).page(1).build(),
725                )
726                .await?;
727            println!("{cos_clan_history:?}");
728            println!("Time elapsed! {:?}", now.elapsed());
729
730            Ok(())
731        }
732
733        #[tokio::test]
734        async fn test_cos_get_best_war_win_streak_leaderboard() -> Result<(), APIError> {
735            let now = Instant::now();
736
737            let cos_clan_history = super::CLIENT
738                .cos_get_best_war_win_streak_leaderboard(
739                    cos_options::Options::builder().location(Local::None).page(1).build(),
740                )
741                .await?;
742            println!("{cos_clan_history:?}");
743            println!("Time elapsed! {:?}", now.elapsed());
744
745            Ok(())
746        }
747
748        #[tokio::test]
749        async fn test_cos_get_clan_trophies_leaderboard() -> Result<(), APIError> {
750            let now = Instant::now();
751
752            let cos_clan_ranking = super::CLIENT
753                .cos_get_clan_trophies_leaderboard(
754                    cos_options::Options::builder().location(Local::None).page(1).build(),
755                )
756                .await?;
757            println!("{cos_clan_ranking:?}");
758            println!("Time elapsed! {:?}", now.elapsed());
759
760            Ok(())
761        }
762
763        #[tokio::test]
764        async fn test_cos_get_clan_versus_trophies_leaderboard() -> Result<(), APIError> {
765            let now = Instant::now();
766
767            let cos_clan_ranking = super::CLIENT
768                .cos_get_clan_versus_trophies_leaderboard(
769                    cos_options::Options::builder().location(Local::None).page(1).build(),
770                )
771                .await?;
772            println!("{cos_clan_ranking:?}");
773            println!("Time elapsed! {:?}", now.elapsed());
774
775            Ok(())
776        }
777
778        #[tokio::test]
779        async fn test_cos_get_player_trophies_leaderboard() -> Result<(), APIError> {
780            let now = Instant::now();
781
782            let cos_player_ranking = super::CLIENT
783                .cos_get_player_trophies_leaderboard(
784                    cos_options::Options::builder().location(Local::UnitedStates).page(1).build(),
785                )
786                .await?;
787            println!("{cos_player_ranking:?}");
788            println!("Time elapsed! {:?}", now.elapsed());
789            Ok(())
790        }
791
792        #[tokio::test]
793        async fn test_cos_get_player_versus_trophies_leaderboard() -> Result<(), APIError> {
794            let now = Instant::now();
795
796            let cos_player_ranking = super::CLIENT
797                .cos_get_player_versus_trophies_leaderboard(
798                    cos_options::Options::builder().location(Local::UnitedStates).page(1).build(),
799                )
800                .await?;
801            println!("{cos_player_ranking:?}");
802            println!("Time elapsed! {:?}", now.elapsed());
803            Ok(())
804        }
805
806        #[tokio::test]
807        async fn test_cos_get_player_best_versus_trophies_leaderboard() -> Result<(), APIError> {
808            let now = Instant::now();
809
810            let cos_player_ranking = super::CLIENT
811                .cos_get_player_best_versus_trophies_leaderboard(
812                    cos_options::Options::builder().location(Local::UnitedStates).page(1).build(),
813                )
814                .await?;
815            println!("{cos_player_ranking:?}");
816            println!("Time elapsed! {:?}", now.elapsed());
817            Ok(())
818        }
819
820        #[tokio::test]
821        async fn test_cos_get_player_legend_trophies_leaderboard() -> Result<(), APIError> {
822            let now = Instant::now();
823
824            let cos_player_versus_trophies_history = super::CLIENT
825                .cos_get_player_legend_trophies_leaderboard(
826                    cos_options::Options::builder().page(5555).build(),
827                )
828                .await?;
829            println!("{cos_player_versus_trophies_history:?}");
830            println!("Time elapsed! {:?}", now.elapsed());
831            Ok(())
832        }
833
834        #[tokio::test]
835        async fn test_cos_get_player_war_stars_leaderboard() -> Result<(), APIError> {
836            let now = Instant::now();
837
838            let cos_player_versus_trophies_history = super::CLIENT
839                .cos_get_player_war_stars_leaderboard(
840                    cos_options::Options::builder().location(Local::UnitedStates).page(1).build(),
841                )
842                .await?;
843            println!("{cos_player_versus_trophies_history:?}");
844            println!("Time elapsed! {:?}", now.elapsed());
845            Ok(())
846        }
847
848        #[tokio::test]
849        async fn test_cos_get_player_cwl_war_stars_leaderboard() -> Result<(), APIError> {
850            let now = Instant::now();
851
852            let cos_player_versus_trophies_history = super::CLIENT
853                .cos_get_player_cwl_war_stars_leaderboard(
854                    cos_options::Options::builder().location(Local::UnitedStates).page(1).build(),
855                )
856                .await?;
857            println!("{cos_player_versus_trophies_history:?}");
858            println!("Time elapsed! {:?}", now.elapsed());
859            Ok(())
860        }
861
862        #[tokio::test]
863        async fn test_cos_get_player_attack_wins_leaderboard() -> Result<(), APIError> {
864            let now = Instant::now();
865
866            let cos_player_versus_trophies_history = super::CLIENT
867                .cos_get_player_attack_wins_leaderboard(
868                    cos_options::Options::builder().location(Local::UnitedStates).page(1).build(),
869                )
870                .await?;
871            println!("{cos_player_versus_trophies_history:?}");
872            println!("Time elapsed! {:?}", now.elapsed());
873            Ok(())
874        }
875
876        #[tokio::test]
877        async fn test_cos_get_player_defense_wins_leaderboard() -> Result<(), APIError> {
878            let now = Instant::now();
879
880            let cos_player_versus_trophies_history = super::CLIENT
881                .cos_get_player_defense_wins_leaderboard(
882                    cos_options::Options::builder().location(Local::UnitedStates).page(1).build(),
883                )
884                .await?;
885            println!("{cos_player_versus_trophies_history:?}");
886            println!("Time elapsed! {:?}", now.elapsed());
887            Ok(())
888        }
889
890        //cos_get_player_versus_battle_wins_leaderboard
891        #[tokio::test]
892        async fn test_cos_get_player_versus_battle_wins_leaderboard() -> Result<(), APIError> {
893            let now = Instant::now();
894
895            let cos_player_versus_trophies_history = super::CLIENT
896                .cos_get_player_versus_battle_wins_leaderboard(
897                    cos_options::Options::builder().location(Local::UnitedStates).page(1).build(),
898                )
899                .await?;
900            println!("{cos_player_versus_trophies_history:?}");
901            println!("Time elapsed! {:?}", now.elapsed());
902            Ok(())
903        }
904
905        #[tokio::test]
906        async fn test_cos_get_player_heroic_heist_leaderboard() -> Result<(), APIError> {
907            let now = Instant::now();
908
909            let cos_player_versus_trophies_history = super::CLIENT
910                .cos_get_player_heroic_heist_leaderboard(
911                    cos_options::Options::builder().location(Local::UnitedStates).page(1).build(),
912                )
913                .await?;
914            println!("{cos_player_versus_trophies_history:?}");
915            println!("Time elapsed! {:?}", now.elapsed());
916            Ok(())
917        }
918
919        #[tokio::test]
920        async fn test_cos_get_player_conqueror_leaderboard() -> Result<(), APIError> {
921            let now = Instant::now();
922
923            let cos_player_versus_trophies_history = super::CLIENT
924                .cos_get_player_conqueror_leaderboard(
925                    cos_options::Options::builder().location(Local::UnitedStates).page(1).build(),
926                )
927                .await?;
928            println!("{cos_player_versus_trophies_history:?}");
929            println!("Time elapsed! {:?}", now.elapsed());
930            Ok(())
931        }
932
933        #[tokio::test]
934        async fn test_cos_get_player_unbreakable_leaderboard() -> Result<(), APIError> {
935            let now = Instant::now();
936
937            let cos_player_versus_trophies_history = super::CLIENT
938                .cos_get_player_unbreakable_leaderboard(
939                    cos_options::Options::builder().location(Local::UnitedStates).page(1).build(),
940                )
941                .await?;
942            println!("{cos_player_versus_trophies_history:?}");
943            println!("Time elapsed! {:?}", now.elapsed());
944            Ok(())
945        }
946
947        #[tokio::test]
948        async fn test_cos_get_player_humiliator_leaderboard() -> Result<(), APIError> {
949            let now = Instant::now();
950
951            let cos_player_versus_trophies_history = super::CLIENT
952                .cos_get_player_humiliator_leaderboard(
953                    cos_options::Options::builder().location(Local::UnitedStates).page(1).build(),
954                )
955                .await?;
956            println!("{cos_player_versus_trophies_history:?}");
957            println!("Time elapsed! {:?}", now.elapsed());
958            Ok(())
959        }
960
961        #[tokio::test]
962        async fn test_cos_get_player_un_build_it_leaderboard() -> Result<(), APIError> {
963            let now = Instant::now();
964
965            let cos_player_versus_trophies_history = super::CLIENT
966                .cos_get_player_un_build_it_leaderboard(
967                    cos_options::Options::builder().location(Local::UnitedStates).page(1).build(),
968                )
969                .await?;
970            println!("{cos_player_versus_trophies_history:?}");
971            println!("Time elapsed! {:?}", now.elapsed());
972            Ok(())
973        }
974
975        #[tokio::test]
976        async fn test_cos_get_player_games_champion_leaderboard() -> Result<(), APIError> {
977            let now = Instant::now();
978
979            let cos_player_versus_trophies_history = super::CLIENT
980                .cos_get_player_games_champion_leaderboard(
981                    cos_options::Options::builder().location(Local::UnitedStates).page(1).build(),
982                )
983                .await?;
984            println!("{cos_player_versus_trophies_history:?}");
985            println!("Time elapsed! {:?}", now.elapsed());
986            Ok(())
987        }
988
989        #[tokio::test]
990        async fn test_cos_get_player_troops_donated_leaderboard() -> Result<(), APIError> {
991            let now = Instant::now();
992
993            let cos_player_versus_trophies_history = super::CLIENT
994                .cos_get_player_troops_donated_leaderboard(
995                    cos_options::Options::builder().location(Local::UnitedStates).page(1).build(),
996                )
997                .await?;
998            println!("{cos_player_versus_trophies_history:?}");
999            println!("Time elapsed! {:?}", now.elapsed());
1000            Ok(())
1001        }
1002
1003        #[tokio::test]
1004        async fn test_cos_get_player_troops_received_leaderboard() -> Result<(), APIError> {
1005            let now = Instant::now();
1006
1007            let cos_player_versus_trophies_history = super::CLIENT
1008                .cos_get_player_troops_received_leaderboard(
1009                    cos_options::Options::builder().location(Local::UnitedStates).page(1).build(),
1010                )
1011                .await?;
1012            println!("{cos_player_versus_trophies_history:?}");
1013            println!("Time elapsed! {:?}", now.elapsed());
1014            Ok(())
1015        }
1016
1017        #[tokio::test]
1018        async fn test_cos_get_player_friend_in_need_leaderboard() -> Result<(), APIError> {
1019            let now = Instant::now();
1020
1021            let cos_player_versus_trophies_history = super::CLIENT
1022                .cos_get_player_friend_in_need_leaderboard(
1023                    cos_options::Options::builder().location(Local::UnitedStates).page(1).build(),
1024                )
1025                .await?;
1026            println!("{cos_player_versus_trophies_history:?}");
1027            println!("Time elapsed! {:?}", now.elapsed());
1028            Ok(())
1029        }
1030
1031        #[tokio::test]
1032        async fn test_cos_get_player_exp_level_leaderboard() -> Result<(), APIError> {
1033            let now = Instant::now();
1034
1035            let cos_player_versus_trophies_history = super::CLIENT
1036                .cos_get_player_exp_level_leaderboard(
1037                    cos_options::Options::builder().location(Local::UnitedStates).page(1).build(),
1038                )
1039                .await?;
1040            println!("{cos_player_versus_trophies_history:?}");
1041            println!("Time elapsed! {:?}", now.elapsed());
1042            Ok(())
1043        }
1044
1045        #[tokio::test]
1046        async fn test_cos_get_player_well_seasoned_leaderboard() -> Result<(), APIError> {
1047            let now = Instant::now();
1048
1049            let cos_player_versus_trophies_history = super::CLIENT
1050                .cos_get_player_well_seasoned_leaderboard(
1051                    cos_options::Options::builder().location(Local::UnitedStates).page(1).build(),
1052                )
1053                .await?;
1054            println!("{cos_player_versus_trophies_history:?}");
1055            println!("Time elapsed! {:?}", now.elapsed());
1056            Ok(())
1057        }
1058
1059        #[tokio::test]
1060        async fn test_cos_get_player_get_those_goblins_leaderboard() -> Result<(), APIError> {
1061            let now = Instant::now();
1062
1063            let cos_player_versus_trophies_history = super::CLIENT
1064                .cos_get_player_get_those_goblins_leaderboard(
1065                    cos_options::Options::builder().location(Local::UnitedStates).page(1).build(),
1066                )
1067                .await?;
1068            println!("{cos_player_versus_trophies_history:?}");
1069            println!("Time elapsed! {:?}", now.elapsed());
1070            Ok(())
1071        }
1072
1073        #[tokio::test]
1074        async fn test_cos_get_player_nice_and_tidy_leaderboard() -> Result<(), APIError> {
1075            let now = Instant::now();
1076
1077            let cos_player_versus_trophies_history = super::CLIENT
1078                .cos_get_player_nice_and_tidy_leaderboard(
1079                    cos_options::Options::builder().location(Local::UnitedStates).page(1).build(),
1080                )
1081                .await?;
1082            println!("{cos_player_versus_trophies_history:?}");
1083            println!("Time elapsed! {:?}", now.elapsed());
1084            Ok(())
1085        }
1086    }
1087}