1use crate::api_v1::{
2 Error as ApiError, GetBeatmapsProps, GetBeatmapsResp, GetUserRecentProp, GetUserRecentResp,
3 OsuApiRequester, UserId,
4};
5use thiserror::Error;
6
7#[derive(Error, Debug)]
8pub enum Error {
9 #[error("there is no record match your given param")]
10 NotFound,
11 #[error("internal error")]
12 Api(#[from] ApiError),
13}
14
15pub struct LatestReplay {
17 pub score: GetUserRecentResp,
18 pub beatmap: GetBeatmapsResp,
19}
20
21pub async fn get_user_latest_replay<'u, C, U>(
23 client: &C,
24 key: &str,
25 user: U,
26) -> Result<LatestReplay, Error>
27where
28 C: OsuApiRequester,
29 U: Into<UserId<'u>>,
30{
31 let prop = GetUserRecentProp::builder()
32 .api_key(key)
33 .user_info(user)
34 .limit(1)
35 .build();
36
37 let mut resp = client.get_user_recent(prop).await?;
38
39 if resp.is_empty() {
40 return Err(Error::NotFound);
41 }
42
43 let user_recent = resp.swap_remove(0);
44
45 let prop = GetBeatmapsProps::builder()
46 .api_key(key)
47 .beatmap_id(user_recent.beatmap_id)
48 .limit(1)
49 .build();
50
51 let mut resp = client.get_beatmaps(prop).await?;
52
53 if resp.is_empty() {
54 return Err(Error::NotFound);
55 }
56
57 let map_info = resp.swap_remove(0);
58
59 Ok(LatestReplay {
60 score: user_recent,
61 beatmap: map_info,
62 })
63}
64
65pub fn gen_beatmap_cover_img_url(set_id: u64) -> reqwest::Url {
67 reqwest::Url::parse(&format!(
68 "https://assets.ppy.sh/beatmaps/{set_id}/covers/cover.jpg"
69 ))
70 .unwrap()
71}
72
73pub fn gen_beatmap_thumbnail(set_id: u64) -> reqwest::Url {
75 reqwest::Url::parse(&format!("https://b.ppy.sh/thumb/{set_id}l.jpg")).unwrap()
76}