use crate::{
model::{GameMode, GameMods},
request::{Request, UserIdentification},
serde::NAIVE_DATETIME_FORMAT,
};
use std::fmt::Write;
use time::OffsetDateTime;
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)]
#[allow(clippy::enum_variant_names)]
pub(crate) enum Route {
GetBeatmaps {
creator: Option<UserIdentification>,
hash: Option<Box<str>>,
limit: Option<u32>,
map_id: Option<u32>,
mapset_id: Option<u32>,
mode: Option<GameMode>,
mods: Option<GameMods>,
since: Option<OffsetDateTime>,
with_converted: Option<bool>,
},
GetMatch { match_id: u32 },
GetScore {
limit: Option<u32>,
map_id: u32,
mode: Option<GameMode>,
mods: Option<GameMods>,
user: Option<UserIdentification>,
},
GetUser {
user: UserIdentification,
mode: Option<GameMode>,
event_days: Option<u32>,
},
GetUserBest {
limit: Option<u32>,
mode: Option<GameMode>,
user: UserIdentification,
},
GetUserRecent {
limit: Option<u32>,
mode: Option<GameMode>,
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(Ok(date)) = since.map(|date| date.format(NAIVE_DATETIME_FORMAT)) {
let _ = write!(uri, "&{}={}", SINCE_TAG, date);
}
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.into_boxed_str())
}
}