use chrono::DateTime;
use chrono::{serde::ts_seconds, Utc};
use serde::Deserialize;
use serde_repr::{Deserialize_repr, Serialize_repr};
use uuid::Uuid;
use crate::types::Time;
use crate::types::{Elo, EloChange, MatchId, Rank, Season};
use crate::user::UserProfile;
pub mod requests;
#[cfg(test)]
mod tests;
pub mod versus;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum MatchCategory {
Any,
Custom,
High,
KillAllBosses,
KillWither,
KillElderGuardian,
AllAdvancements,
Half,
PoglootQuater,
HowDidWeGetHere,
HeroOfTheVillage,
Arbalistic,
CoverMeInDebris,
EnterNether,
EnterEnd,
AllSwords,
AllMinerals,
#[serde(rename = "FULL_IA_15_LVL")]
FullIa15Lvl,
AllWorkstations,
FullInv,
StackOfLimeWool,
AllPortals,
AllBlocks,
MineAChunk,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
pub struct MatchSeedInfo {
id: Option<Box<str>>,
overworld: Option<OverworldType>,
bastion: Option<BastionType>,
variations: Box<[Box<str>]>,
}
impl MatchSeedInfo {
pub fn id(&self) -> Option<&str> {
self.id.as_ref().map(AsRef::as_ref)
}
pub fn overworld(&self) -> Option<OverworldType> {
self.overworld
}
pub fn bastion(&self) -> Option<BastionType> {
self.bastion
}
pub fn variations(&self) -> &[Box<str>] {
&self.variations
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize_repr, Serialize_repr)]
#[repr(u8)]
pub enum MatchType {
Causal = 1,
Ranked = 2,
Private = 3,
Event = 4,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct MatchOutcome {
#[serde(rename = "uuid")]
winner_uuid: Option<Uuid>,
time: Time,
}
impl MatchOutcome {
pub fn winner_uuid(&self) -> Option<Uuid> {
self.winner_uuid
}
pub fn time(&self) -> Time {
self.time
}
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct MatchRank {
season: Option<Rank>,
all_time: Option<Rank>,
}
impl MatchRank {
pub fn season(&self) -> Option<Rank> {
self.season
}
pub fn all_time(&self) -> Option<Rank> {
self.all_time
}
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct MatchEloUpdate {
#[serde(rename = "uuid")]
player_uuid: Uuid,
change: Option<EloChange>,
#[serde(rename = "eloRate")]
elo: Option<Elo>,
}
impl MatchEloUpdate {
pub fn player_uuid(&self) -> Uuid {
self.player_uuid
}
pub fn elo_change(&self) -> Option<EloChange> {
self.change
}
pub fn elo(&self) -> Option<Elo> {
self.elo
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum OverworldType {
Village,
BuriedTreasure,
Shipwreck,
RuinedPortal,
DesertTemple,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
pub enum BastionType {
Housing,
Treasure,
Bridge,
Stables,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct MatchCompletion {
#[serde(rename = "uuid")]
player_uuid: Uuid,
time: Time,
}
impl MatchCompletion {
pub fn player_uuid(&self) -> Uuid {
self.player_uuid
}
pub fn time(&self) -> Time {
self.time
}
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct MatchTimelineEvent {
#[serde(rename = "uuid")]
player_uuid: Uuid,
time: Time,
#[serde(rename = "type")]
id: Box<str>,
}
impl MatchTimelineEvent {
pub fn player_uuid(&self) -> Uuid {
self.player_uuid
}
pub fn time(&self) -> Time {
self.time
}
pub fn id(&self) -> &str {
&self.id
}
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct MatchInfo {
id: MatchId,
#[serde(rename = "type")]
kind: MatchType,
season: Season,
category: MatchCategory,
#[serde(with = "ts_seconds")]
date: DateTime<Utc>,
players: Box<[UserProfile]>,
spectators: Box<[UserProfile]>,
seed: MatchSeedInfo,
result: MatchOutcome,
forfeited: bool,
decayed: bool,
rank: MatchRank,
changes: Box<[MatchEloUpdate]>,
}
impl MatchInfo {
pub fn id(&self) -> MatchId {
self.id
}
pub fn kind(&self) -> MatchType {
self.kind
}
pub fn season(&self) -> Season {
self.season
}
pub fn category(&self) -> MatchCategory {
self.category
}
pub fn date(&self) -> DateTime<Utc> {
self.date
}
pub fn players(&self) -> &[UserProfile] {
&self.players
}
pub fn spectators(&self) -> &[UserProfile] {
&self.spectators
}
pub fn seed_info(&self) -> &MatchSeedInfo {
&self.seed
}
pub fn result(&self) -> &MatchOutcome {
&self.result
}
pub fn forfeited(&self) -> bool {
self.forfeited
}
pub fn decayed(&self) -> bool {
self.decayed
}
pub fn rank(&self) -> &MatchRank {
&self.rank
}
pub fn elo_updates(&self) -> &[MatchEloUpdate] {
&self.changes
}
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AdvancedMatchInfo {
#[serde(flatten)]
info: MatchInfo,
completions: Box<[MatchCompletion]>,
timelines: Box<[MatchTimelineEvent]>,
replay_exist: bool,
}
impl AdvancedMatchInfo {
pub fn completions(&self) -> &[MatchCompletion] {
&self.completions
}
pub fn timeline_events(&self) -> &[MatchTimelineEvent] {
&self.timelines
}
pub fn replay_exists(&self) -> bool {
self.replay_exist
}
}