osu_api/api_v1/models/
recent.rs

1use std::collections::HashMap;
2
3use super::{
4  de::{s_to_bool, s_to_datetime, s_to_mods_flags, s_to_u32, s_to_u64},
5  GameMode, ModsFlag, UserId,
6};
7use serde::Deserialize;
8use typed_builder::TypedBuilder;
9
10#[derive(TypedBuilder, Debug)]
11pub struct GetUserRecentProp<'k, 'u> {
12  api_key: &'k str,
13  #[builder(setter(transform = |id: impl Into<UserId<'u>>| id.into()))]
14  user_info: UserId<'u>,
15  #[builder(default, setter(strip_option))]
16  mode: Option<GameMode>,
17  #[builder(default = 10)]
18  limit: u8,
19}
20
21impl<'k, 'u> From<GetUserRecentProp<'k, 'u>> for HashMap<&'static str, String> {
22  fn from(prop: GetUserRecentProp<'k, 'u>) -> Self {
23    let mut query = Self::new();
24
25    query.insert("k", prop.api_key.to_string());
26
27    match prop.user_info {
28      UserId::Id(number) => {
29        query.insert("u", number.to_string());
30      }
31      UserId::Username(name) => {
32        // Osu! API server will recognize name consist with only number as user ID,
33        // so we must explicit set `type` to `string` here to avoid misunderstanding.
34        query.insert("type", "string".to_string());
35        query.insert("u", name.to_string());
36      }
37    };
38
39    if let Some(mode) = prop.mode {
40      query.insert("m", mode.to_string());
41    }
42
43    query.insert("limit", prop.limit.to_string());
44
45    query
46  }
47}
48
49#[derive(Deserialize, Debug)]
50pub struct GetUserRecentResp {
51  pub rank: String,
52  pub user_id: String,
53  #[serde(deserialize_with = "s_to_u64")]
54  pub beatmap_id: u64,
55  #[serde(deserialize_with = "s_to_u64")]
56  pub score: u64,
57  #[serde(deserialize_with = "s_to_u32")]
58  pub maxcombo: u32,
59  #[serde(deserialize_with = "s_to_u32")]
60  pub count50: u32,
61  #[serde(deserialize_with = "s_to_u32")]
62  pub count100: u32,
63  #[serde(deserialize_with = "s_to_u32")]
64  pub count300: u32,
65  #[serde(deserialize_with = "s_to_u32")]
66  pub countmiss: u32,
67  #[serde(deserialize_with = "s_to_u32")]
68  pub countkatu: u32,
69  #[serde(deserialize_with = "s_to_u32")]
70  pub countgeki: u32,
71  #[serde(deserialize_with = "s_to_bool")]
72  pub perfect: bool,
73  #[serde(deserialize_with = "s_to_mods_flags")]
74  pub enabled_mods: ModsFlag,
75  #[serde(deserialize_with = "s_to_datetime")]
76  pub date: chrono::DateTime<chrono::Utc>,
77}