1use crate::{
2 model::{
3 ranking::{ChartRankings, CountryRankings, RankingType, Rankings, Spotlight},
4 user::CountryCode,
5 DeserializedList, GameMode,
6 },
7 prelude::TeamRankings,
8 request::{Query, Request},
9 routing::Route,
10 Osu,
11};
12
13use serde::Serialize;
14
15#[must_use = "requests must be configured and executed"]
28#[derive(Serialize)]
29pub struct GetChartRankings<'a> {
30 #[serde(skip)]
31 osu: &'a Osu,
32 #[serde(skip)]
33 mode: GameMode,
34 spotlight: Option<u32>,
35}
36
37impl<'a> GetChartRankings<'a> {
38 pub(crate) const fn new(osu: &'a Osu, mode: GameMode) -> Self {
39 Self {
40 osu,
41 mode,
42 spotlight: None,
43 }
44 }
45
46 #[inline]
49 pub const fn spotlight(mut self, spotlight_id: u32) -> Self {
50 self.spotlight = Some(spotlight_id);
51
52 self
53 }
54}
55
56into_future! {
57 |self: GetChartRankings<'_>| -> ChartRankings {
58 Request::with_query(
59 Route::GetRankings {
60 mode: self.mode,
61 ranking_type: RankingType::Charts,
62 },
63 Query::encode(&self),
64 )
65 }
66}
67
68#[must_use = "requests must be configured and executed"]
73#[derive(Serialize)]
74pub struct GetCountryRankings<'a> {
75 #[serde(skip)]
76 osu: &'a Osu,
77 #[serde(skip)]
78 mode: GameMode,
79 #[serde(rename(serialize = "cursor[page]"))]
80 page: Option<u32>,
81}
82
83impl<'a> GetCountryRankings<'a> {
84 pub(crate) const fn new(osu: &'a Osu, mode: GameMode) -> Self {
85 Self {
86 osu,
87 mode,
88 page: None,
89 }
90 }
91
92 #[inline]
94 pub const fn page(mut self, page: u32) -> Self {
95 self.page = Some(page);
96
97 self
98 }
99}
100
101into_future! {
102 |self: GetCountryRankings<'_>| -> CountryRankings {
103 Request::with_query(
104 Route::GetRankings {
105 mode: self.mode,
106 ranking_type: RankingType::Country,
107 },
108 Query::encode(&self),
109 )
110 }
111}
112
113#[must_use = "requests must be configured and executed"]
118#[derive(Serialize)]
119pub struct GetPerformanceRankings<'a> {
120 #[serde(skip)]
121 osu: &'a Osu,
122 #[serde(skip)]
123 mode: GameMode,
124 country: Option<CountryCode>,
125 variant: Option<&'static str>,
126 #[serde(rename(serialize = "cursor[page]"))]
127 page: Option<u32>,
128}
129
130impl<'a> GetPerformanceRankings<'a> {
131 pub(crate) const fn new(osu: &'a Osu, mode: GameMode) -> Self {
132 Self {
133 osu,
134 mode,
135 country: None,
136 variant: None,
137 page: None,
138 }
139 }
140
141 #[inline]
143 pub fn country(mut self, country: impl Into<CountryCode>) -> Self {
144 self.country = Some(country.into());
145
146 self
147 }
148
149 #[inline]
151 pub const fn variant_4k(mut self) -> Self {
152 self.variant = Some("4k");
153
154 self
155 }
156
157 #[inline]
159 pub const fn variant_7k(mut self) -> Self {
160 self.variant = Some("7k");
161
162 self
163 }
164
165 #[inline]
167 pub const fn page(mut self, page: u32) -> Self {
168 self.page = Some(page);
169
170 self
171 }
172}
173
174into_future! {
175 |self: GetPerformanceRankings<'_>| -> Rankings {
176 let req = Request::with_query(
177 Route::GetRankings {
178 mode: self.mode,
179 ranking_type: RankingType::Performance,
180 },
181 Query::encode(&self),
182 );
183
184 (req, self.mode)
185 } => |rankings, mode: GameMode| -> Rankings {
186 rankings.mode = Some(mode);
187 rankings.ranking_type = Some(RankingType::Performance);
188
189 Ok(rankings)
190 }
191}
192
193#[must_use = "requests must be configured and executed"]
198#[derive(Serialize)]
199pub struct GetScoreRankings<'a> {
200 #[serde(skip)]
201 osu: &'a Osu,
202 #[serde(skip)]
203 mode: GameMode,
204 #[serde(rename(serialize = "cursor[page]"))]
205 page: Option<u32>,
206}
207
208impl<'a> GetScoreRankings<'a> {
209 pub(crate) const fn new(osu: &'a Osu, mode: GameMode) -> Self {
210 Self {
211 osu,
212 mode,
213 page: None,
214 }
215 }
216
217 #[inline]
219 pub const fn page(mut self, page: u32) -> Self {
220 self.page = Some(page);
221
222 self
223 }
224}
225
226into_future! {
227 |self: GetScoreRankings<'_>| -> Rankings {
228 let req = Request::with_query(
229 Route::GetRankings {
230 mode: self.mode,
231 ranking_type: RankingType::Score,
232 },
233 Query::encode(&self)
234 );
235
236 (req, self.mode)
237 } => |rankings, mode: GameMode| -> Rankings {
238 rankings.mode = Some(mode);
239 rankings.ranking_type = Some(RankingType::Score);
240
241 Ok(rankings)
242 }
243}
244
245#[must_use = "requests must be configured and executed"]
247pub struct GetSpotlights<'a> {
248 osu: &'a Osu,
249}
250
251impl<'a> GetSpotlights<'a> {
252 pub(crate) const fn new(osu: &'a Osu) -> Self {
253 Self { osu }
254 }
255}
256
257into_future! {
258 |self: GetSpotlights<'_>| -> DeserializedList<Spotlight> {
259 Request::new(Route::GetSpotlights)
260 } => |spotlights, _| -> Vec<Spotlight> {
261 Ok(spotlights.0)
262 }
263}
264
265#[must_use = "requests must be configured and executed"]
267#[derive(Serialize)]
268pub struct GetTeamRankings<'a> {
269 #[serde(skip)]
270 osu: &'a Osu,
271 #[serde(skip)]
272 mode: GameMode,
273 #[serde(rename(serialize = "cursor[page]"))]
274 page: Option<u32>,
275}
276
277impl<'a> GetTeamRankings<'a> {
278 pub(crate) const fn new(osu: &'a Osu, mode: GameMode) -> Self {
279 Self {
280 osu,
281 mode,
282 page: None,
283 }
284 }
285
286 #[inline]
288 pub const fn page(mut self, page: u32) -> Self {
289 self.page = Some(page);
290
291 self
292 }
293}
294
295into_future! {
296 |self: GetTeamRankings<'_>| -> TeamRankings {
297 let req = Request::with_query(
298 Route::GetRankings {
299 mode: self.mode,
300 ranking_type: RankingType::Team,
301 },
302 Query::encode(&self),
303 );
304
305 (req, self.mode)
306 } => |rankings, mode: GameMode| -> TeamRankings {
307 rankings.mode = Some(mode);
308
309 Ok(rankings)
310 }
311}