rosu_v2/request/
score.rs

1use rosu_mods::GameMode;
2use serde::Serialize;
3
4use crate::{
5    prelude::{ProcessedScores, Score},
6    routing::Route,
7    Osu,
8};
9
10use super::{serialize::maybe_mode_as_str, Query, Request};
11
12/// Get a [`Score`] struct.
13#[must_use = "requests must be configured and executed"]
14pub struct GetScore<'a> {
15    osu: &'a Osu,
16    mode: Option<GameMode>,
17    score_id: u64,
18    legacy_scores: bool,
19}
20
21impl<'a> GetScore<'a> {
22    pub(crate) const fn new(osu: &'a Osu, score_id: u64) -> Self {
23        Self {
24            osu,
25            mode: None,
26            score_id,
27            legacy_scores: false,
28        }
29    }
30
31    /// Specify the mode
32    #[inline]
33    pub const fn mode(mut self, mode: GameMode) -> Self {
34        self.mode = Some(mode);
35
36        self
37    }
38
39    /// Specify whether the score should contain legacy data or not.
40    ///
41    /// Legacy data consists of a different grade calculation, less
42    /// populated statistics, legacy mods, and a different score kind.
43    #[inline]
44    pub const fn legacy_scores(mut self, legacy_scores: bool) -> Self {
45        self.legacy_scores = legacy_scores;
46
47        self
48    }
49}
50
51into_future! {
52    |self: GetScore<'_>| -> Score {
53        let route = Route::GetScore {
54            mode: self.mode,
55            score_id: self.score_id,
56        };
57
58        let mut req = Request::new(route);
59
60        if self.legacy_scores {
61            req.api_version(0);
62        }
63
64        req
65    }
66}
67
68/// Get a list of recently processed [`Score`] structs.
69#[must_use = "requests must be configured and executed"]
70#[derive(Serialize)]
71pub struct GetScores<'a> {
72    #[serde(skip)]
73    osu: &'a Osu,
74    #[serde(rename(serialize = "ruleset"), serialize_with = "maybe_mode_as_str")]
75    mode: Option<GameMode>,
76    #[serde(rename(serialize = "cursor[id]"))]
77    score_id: Option<u64>,
78    #[serde(rename(serialize = "cursor_string"))]
79    cursor: Option<Box<str>>,
80}
81
82impl<'a> GetScores<'a> {
83    pub(crate) const fn new(osu: &'a Osu) -> Self {
84        Self {
85            osu,
86            mode: None,
87            score_id: None,
88            cursor: None,
89        }
90    }
91
92    /// Specify the mode
93    pub const fn mode(mut self, mode: GameMode) -> Self {
94        self.mode = Some(mode);
95
96        self
97    }
98
99    /// Fetch from the given score id onward
100    pub const fn score_id(mut self, score_id: u64) -> Self {
101        self.score_id = Some(score_id);
102
103        self
104    }
105
106    /// Specify a cursor
107    pub fn cursor(mut self, cursor: Box<str>) -> Self {
108        self.cursor = Some(cursor);
109
110        self
111    }
112}
113
114into_future! {
115    |self: GetScores<'_>| -> ProcessedScores {
116        (Request::with_query(Route::GetScores, Query::encode(&self)), self.mode)
117    } => |scores, mode: Option<GameMode>| -> ProcessedScores {
118        scores.mode = mode;
119
120        Ok(scores)
121    }
122}