use crate::model::prelude::*;
use std::collections::HashMap;
#[derive(Clone, Debug, Deserialize)]
#[non_exhaustive]
pub struct Record {
#[serde(rename = "_id")]
pub id: String,
#[serde(rename = "replayid")]
pub replay_id: ReplayId,
#[serde(rename = "stub")]
pub is_stub: bool,
#[serde(rename = "gamemode")]
pub game_mode: Gamemode,
#[serde(rename = "pb")]
pub is_personal_best: bool,
#[serde(rename = "oncepb")]
pub has_been_personal_best: bool,
#[serde(rename = "ts")]
pub submitted_at: Timestamp,
pub revolution: Option<String>,
pub user: Option<PartialUser>,
#[serde(rename = "otherusers")]
pub other_users: Vec<PartialUser>,
pub leaderboards: Vec<RecordLeaderboardModel>,
#[serde(rename = "disputed")]
pub is_disputed: bool,
pub results: Results,
pub extras: Extras,
#[serde(rename = "p")]
pub prisecter: Option<Prisecter>,
}
impl Record {
impl_for_replay_id!();
impl_for_submitted_at!();
}
impl AsRef<Record> for Record {
fn as_ref(&self) -> &Self {
self
}
}
#[derive(Clone, Debug, Deserialize)]
#[non_exhaustive]
pub struct PartialUser {
pub id: UserId,
pub username: String,
pub avatar_revision: Option<u64>,
pub banner_revision: Option<u64>,
pub country: Option<String>,
#[serde(rename = "supporter")]
#[serde(default)] pub is_supporter: bool,
}
impl PartialUser {
impl_get_user!(id);
impl_for_username!();
impl_for_avatar_revision!();
impl_for_banner_revision!();
impl_for_country!();
}
impl AsRef<PartialUser> for PartialUser {
fn as_ref(&self) -> &Self {
self
}
}
#[derive(Clone, Debug, Deserialize)]
#[serde(untagged)]
#[non_exhaustive]
pub enum Results {
SinglePlayer(SinglePlayerResults),
MultiPlayer(MultiPlayerResults),
Unknown(serde_json::Value),
}
impl Results {
pub fn is_single_play(&self) -> bool {
matches!(self, Results::SinglePlayer(_))
}
pub fn is_multi_play(&self) -> bool {
matches!(self, Results::MultiPlayer(_))
}
pub fn is_unknown_structure(&self) -> bool {
matches!(self, Results::Unknown(_))
}
}
impl AsRef<Results> for Results {
fn as_ref(&self) -> &Self {
self
}
}
#[derive(Clone, Debug, Deserialize)]
#[non_exhaustive]
pub struct SinglePlayerResults {
#[serde(rename = "stats")]
pub final_stats: serde_json::Value,
#[serde(rename = "aggregatestats")]
pub aggregate_stats: serde_json::Value,
#[serde(rename = "gameoverreason")]
pub game_over_reason: String,
}
impl AsRef<SinglePlayerResults> for SinglePlayerResults {
fn as_ref(&self) -> &Self {
self
}
}
#[derive(Clone, Debug, Deserialize)]
#[non_exhaustive]
pub struct MultiPlayerResults {
pub leaderboard: Vec<PlayerStats>,
pub rounds: Vec<Vec<PlayerStatsRound>>,
}
impl AsRef<MultiPlayerResults> for MultiPlayerResults {
fn as_ref(&self) -> &Self {
self
}
}
#[derive(Clone, Debug, Deserialize)]
#[non_exhaustive]
pub struct PlayerStats {
pub id: UserId,
pub username: String,
#[serde(rename = "active")]
pub is_active: bool,
pub wins: u32,
pub stats: serde_json::Value,
}
impl PlayerStats {
impl_get_user!(id);
impl_for_username!();
}
impl AsRef<PlayerStats> for PlayerStats {
fn as_ref(&self) -> &Self {
self
}
}
#[derive(Clone, Debug, Deserialize)]
#[non_exhaustive]
pub struct PlayerStatsRound {
pub id: UserId,
pub username: String,
#[serde(rename = "active")]
pub is_active: bool,
#[serde(rename = "alive")]
pub is_alive: bool,
pub lifetime: u32,
pub stats: serde_json::Value,
}
impl PlayerStatsRound {
impl_get_user!(id);
impl_for_username!();
}
impl AsRef<PlayerStatsRound> for PlayerStatsRound {
fn as_ref(&self) -> &Self {
self
}
}
#[derive(Clone, Debug, Deserialize)]
#[non_exhaustive]
pub struct Extras {
pub league: Option<HashMap<UserId, Vec<PlayerExtraStats>>>,
pub result: Option<String>,
pub zenith: Option<Zenith>,
}
impl AsRef<Extras> for Extras {
fn as_ref(&self) -> &Self {
self
}
}
#[derive(Clone, Debug, Deserialize)]
#[non_exhaustive]
pub struct PlayerExtraStats {
pub glicko: f64,
pub rd: f64,
pub tr: f64,
pub rank: Rank,
pub placement: Option<u32>,
}
impl AsRef<PlayerExtraStats> for PlayerExtraStats {
fn as_ref(&self) -> &Self {
self
}
}
#[derive(Clone, Debug, Deserialize)]
#[non_exhaustive]
pub struct Zenith {
pub mods: Vec<String>,
}
impl AsRef<Zenith> for Zenith {
fn as_ref(&self) -> &Self {
self
}
}