#![allow(clippy::enum_variant_names)]
use crate::{
model::{GameMode, GameMods},
request::{Request, UserIdentification},
};
#[cfg(feature = "cache")]
use crate::serde::serde_maybe_date;
use chrono::{DateTime, Utc};
use std::fmt::Write;
#[cfg(feature = "cache")]
use serde::{Deserialize, Serialize};
const CONV_TAG: &str = "a";
const EVENT_DAYS_TAG: &str = "event_days";
const HASH_TAG: &str = "h";
const LIMIT_TAG: &str = "limit";
const MAP_TAG: &str = "b";
const MODE_TAG: &str = "m";
const MODS_TAG: &str = "mods";
const MP_TAG: &str = "mp";
const SET_TAG: &str = "s";
const SINCE_TAG: &str = "since";
#[derive(Debug)]
#[cfg_attr(feature = "cache", derive(Deserialize, Serialize))]
pub(crate) enum Route {
#[cfg_attr(feature = "cache", serde(rename = "A"))]
GetBeatmaps {
#[cfg_attr(
feature = "cache",
serde(rename = "a", default, skip_serializing_if = "Option::is_none")
)]
creator: Option<UserIdentification>,
#[cfg_attr(
feature = "cache",
serde(rename = "b", default, skip_serializing_if = "Option::is_none")
)]
hash: Option<String>,
#[cfg_attr(
feature = "cache",
serde(rename = "c", default, skip_serializing_if = "Option::is_none")
)]
limit: Option<u32>,
#[cfg_attr(
feature = "cache",
serde(rename = "d", default, skip_serializing_if = "Option::is_none")
)]
map_id: Option<u32>,
#[cfg_attr(
feature = "cache",
serde(rename = "e", default, skip_serializing_if = "Option::is_none")
)]
mapset_id: Option<u32>,
#[cfg_attr(
feature = "cache",
serde(rename = "f", default, skip_serializing_if = "Option::is_none")
)]
mode: Option<GameMode>,
#[cfg_attr(
feature = "cache",
serde(rename = "g", default, skip_serializing_if = "Option::is_none")
)]
mods: Option<GameMods>,
#[cfg_attr(
feature = "cache",
serde(
rename = "h",
with = "serde_maybe_date",
default,
skip_serializing_if = "Option::is_none"
)
)]
since: Option<DateTime<Utc>>,
#[cfg_attr(
feature = "cache",
serde(rename = "i", default, skip_serializing_if = "Option::is_none")
)]
with_converted: Option<bool>,
},
#[cfg_attr(feature = "cache", serde(rename = "B"))]
GetMatch {
#[cfg_attr(feature = "cache", serde(rename = "a"))]
match_id: u32,
},
#[cfg_attr(feature = "cache", serde(rename = "C"))]
GetScore {
#[cfg_attr(
feature = "cache",
serde(rename = "a", default, skip_serializing_if = "Option::is_none")
)]
limit: Option<u32>,
#[cfg_attr(feature = "cache", serde(rename = "b"))]
map_id: u32,
#[cfg_attr(
feature = "cache",
serde(rename = "c", default, skip_serializing_if = "Option::is_none")
)]
mode: Option<GameMode>,
#[cfg_attr(
feature = "cache",
serde(rename = "d", default, skip_serializing_if = "Option::is_none")
)]
mods: Option<GameMods>,
#[cfg_attr(
feature = "cache",
serde(rename = "e", default, skip_serializing_if = "Option::is_none")
)]
user: Option<UserIdentification>,
},
#[cfg_attr(feature = "cache", serde(rename = "D"))]
GetUser {
#[cfg_attr(feature = "cache", serde(rename = "a"))]
user: UserIdentification,
#[cfg_attr(
feature = "cache",
serde(rename = "b", default, skip_serializing_if = "Option::is_none")
)]
mode: Option<GameMode>,
#[cfg_attr(
feature = "cache",
serde(rename = "c", default, skip_serializing_if = "Option::is_none")
)]
event_days: Option<u32>,
},
#[cfg_attr(feature = "cache", serde(rename = "E"))]
GetUserBest {
#[cfg_attr(
feature = "cache",
serde(rename = "a", default, skip_serializing_if = "Option::is_none")
)]
limit: Option<u32>,
#[cfg_attr(
feature = "cache",
serde(rename = "b", default, skip_serializing_if = "Option::is_none")
)]
mode: Option<GameMode>,
#[cfg_attr(feature = "cache", serde(rename = "c"))]
user: UserIdentification,
},
#[cfg_attr(feature = "cache", serde(rename = "F"))]
GetUserRecent {
#[cfg_attr(
feature = "cache",
serde(rename = "a", default, skip_serializing_if = "Option::is_none")
)]
limit: Option<u32>,
#[cfg_attr(
feature = "cache",
serde(rename = "b", default, skip_serializing_if = "Option::is_none")
)]
mode: Option<GameMode>,
#[cfg_attr(feature = "cache", serde(rename = "c"))]
user: UserIdentification,
},
}
impl From<Route> for Request {
fn from(route: Route) -> Self {
let uri = match route {
Route::GetBeatmaps {
creator,
hash,
limit,
map_id,
mapset_id,
mode,
mods,
since,
with_converted,
} => {
let mut uri = String::from("get_beatmaps?");
if let Some(creator) = creator {
let _ = write!(uri, "&{}", creator);
}
if let Some(hash) = hash {
let _ = write!(uri, "&{}={}", HASH_TAG, hash);
}
if let Some(limit) = limit {
let _ = write!(uri, "&{}={}", LIMIT_TAG, limit);
}
if let Some(map_id) = map_id {
let _ = write!(uri, "&{}={}", MAP_TAG, map_id);
}
if let Some(mapset_id) = mapset_id {
let _ = write!(uri, "&{}={}", SET_TAG, mapset_id);
}
if let Some(mode) = mode {
let _ = write!(uri, "&{}={}", MODE_TAG, mode as u8);
}
if let Some(mods) = mods {
let _ = write!(uri, "&{}={}", MODS_TAG, mods.bits());
}
if let Some(date) = since {
let _ = write!(uri, "&{}={}", SINCE_TAG, date.format("%F%%T"));
}
if let Some(with_converted) = with_converted {
let _ = write!(uri, "&{}={}", CONV_TAG, with_converted as u8);
}
uri
}
Route::GetMatch { match_id } => format!("get_match?{}={}", MP_TAG, match_id),
Route::GetScore {
limit,
map_id,
mode,
mods,
user,
} => {
let mut uri = format!("get_scores?{}={}", MAP_TAG, map_id);
if let Some(limit) = limit {
let _ = write!(uri, "&{}={}", LIMIT_TAG, limit);
}
if let Some(mode) = mode {
let _ = write!(uri, "&{}={}", MODE_TAG, mode as u8);
}
if let Some(mods) = mods {
let _ = write!(uri, "&{}={}", MODS_TAG, mods.bits());
}
if let Some(user) = user {
let _ = write!(uri, "&{}", user);
}
uri
}
Route::GetUser {
user,
mode,
event_days,
} => {
let mut uri = format!("get_user?{}", user);
if let Some(mode) = mode {
let _ = write!(uri, "&{}={}", MODE_TAG, mode as u8);
}
if let Some(days) = event_days {
let _ = write!(uri, "&{}={}", EVENT_DAYS_TAG, days);
}
uri
}
Route::GetUserBest { limit, mode, user } => {
let mut uri = format!("get_user_best?{}", user);
if let Some(limit) = limit {
let _ = write!(uri, "&{}={}", LIMIT_TAG, limit);
}
if let Some(mode) = mode {
let _ = write!(uri, "&{}={}", MODE_TAG, mode as u8);
}
uri
}
Route::GetUserRecent { limit, mode, user } => {
let mut uri = format!("get_user_recent?{}", user);
if let Some(limit) = limit {
let _ = write!(uri, "&{}={}", LIMIT_TAG, limit);
}
if let Some(mode) = mode {
let _ = write!(uri, "&{}={}", MODE_TAG, mode as u8);
}
uri
}
};
Request(uri)
}
}