1use std::collections::HashMap;
2
3use crate::api_v1::{
4 ApiEndpoint, Error, GetBeatmapsProps, GetBeatmapsResp, GetUserRecentProp, GetUserRecentResp,
5 OsuApiRequester,
6};
7
8type QueryParam = HashMap<&'static str, String>;
9
10#[async_trait::async_trait]
11impl OsuApiRequester for reqwest::Client {
12 async fn get_user_recent<'k, 'u>(
13 &self,
14 param: GetUserRecentProp<'k, 'u>,
15 ) -> Result<Vec<GetUserRecentResp>, Error> {
16 let param: QueryParam = param.into();
17 let url = reqwest::Url::parse_with_params(ApiEndpoint::GET_USER_RECENT, ¶m)
18 .expect("fail to turn GetUserRecentProp into params");
19 let resp = self.get(url).send().await?.bytes().await?;
20 let recent: Vec<GetUserRecentResp> = serde_json::from_slice(&resp)?;
21
22 Ok(recent)
23 }
24
25 async fn get_beatmaps<'u, 'k>(
26 &self,
27 param: GetBeatmapsProps<'u, 'k>,
28 ) -> Result<Vec<GetBeatmapsResp>, Error> {
29 let param: HashMap<&'static str, String> =
30 param.try_into().map_err(|_| Error::InvalidRequestParams)?;
31 let url = reqwest::Url::parse_with_params(ApiEndpoint::GET_BEATMAPS, ¶m)
32 .expect("fail to turn given param into query");
33 let resp = self.get(url).send().await?.bytes().await?;
34 let recent: Vec<GetBeatmapsResp> = serde_json::from_slice(&resp)?;
35 Ok(recent)
36 }
37}
38
39#[tokio::test]
40async fn test_get_user_recent() {
41 dotenvy::dotenv().ok();
42
43 let api_key = std::env::var("OSU_API_KEY").expect("Require env `OSU_API_KEY` set");
44
45 let props = GetUserRecentProp::builder()
46 .api_key(&api_key)
47 .user_info("BlackDog5")
48 .limit(1)
49 .build();
50 let client = reqwest::Client::new();
51 let resp = client.get_user_recent(props).await.unwrap();
52
53 assert!(!resp.is_empty())
54}
55
56#[tokio::test]
57async fn test_get_beatmaps() {
58 dotenvy::dotenv().ok();
59
60 let api_key = std::env::var("OSU_API_KEY").expect("Require env `OSU_API_KEY` set");
61 let client = reqwest::Client::new();
62
63 let props = GetBeatmapsProps::builder()
65 .api_key(&api_key)
66 .beatmapset_id(896080)
67 .build();
68 let resp = client.get_beatmaps(props).await.unwrap();
69 assert_eq!(resp.len(), 3);
71
72 let props = GetBeatmapsProps::builder()
74 .api_key(&api_key)
75 .beatmap_id(1872396)
76 .build();
77 let resp = client.get_beatmaps(props).await.unwrap();
78 assert_eq!(resp.len(), 1);
79
80 use super::ModsFlag;
81
82 let props = GetBeatmapsProps::builder()
84 .api_key(&api_key)
85 .beatmap_id(1872396)
86 .mods(vec![ModsFlag::DOUBLETIME, ModsFlag::EASY])
87 .build();
88 let resp = client.get_beatmaps(props).await.unwrap();
89 assert!(!resp.is_empty());
90
91 let map = &resp[0];
93 assert!(map.difficultyrating > 6.01);
94}