use std::{collections::BTreeMap, str::FromStr};
use serde::Deserialize;
use serde_with::{serde_as,json::JsonString, DeserializeFromStr};
use crate::type_search::Gender;
#[derive(Debug, Deserialize)]
#[serde(untagged)]
pub enum GetInfoContent {
Event(Event),
EloPerSeason(BTreeMap<Season,u32>),
}
impl GetInfoContent {
pub fn event(self)->Option<Event>{
match self {
GetInfoContent::Event(e) => Some(e),
_ => None,
}
}
pub fn elo_per_season(self)->Option<EloPerSeason>{
match self {
GetInfoContent::EloPerSeason(e) => {
Some(EloPerSeason(e))
},
_ => None,
}
}
}
#[derive(Debug,PartialEq, Eq,Clone, Copy)]
pub enum YearSlot {
Spring,
Autumn
}
#[derive(Debug,Deserialize)]
pub enum Division {
Landelijk,
#[serde(alias = "zuidwest", alias = "Zuidwest")]
ZuidWest,
West,
Noord,
Oost,
Midden,
Limburg,
#[serde(alias = "NoordHolland", alias = "Holland-Noord")]
HollandNoord,
Gelge
}
#[derive(Debug,Deserialize)]
pub enum Selection {
#[serde(alias="allen")]
Allen,
Dames,
Heren,
Jeugd,
Jongens,
Junioren,
Meisjes,
Senioren
}
#[derive(Debug,DeserializeFromStr,PartialEq, Eq)]
pub struct Season {
pub year:u32,
pub slot:YearSlot
}
impl PartialOrd for Season {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
match (self.year == other.year, self.slot == other.slot) {
(true,true) => Some(std::cmp::Ordering::Equal),
(true,false) => match (self.slot,other.slot) {
(YearSlot::Spring,YearSlot::Autumn) => Some(std::cmp::Ordering::Less),
(YearSlot::Autumn,YearSlot::Spring) => Some(std::cmp::Ordering::Greater),
(_,_) => Some(std::cmp::Ordering::Equal)
},
(_,_) => {
if self.year < other.year {
Some(std::cmp::Ordering::Less)
}else {
Some(std::cmp::Ordering::Greater)
}
}
}
}
}
impl Ord for Season {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.partial_cmp(other).unwrap_or(std::cmp::Ordering::Equal)
}
}
impl FromStr for Season {
type Err = crate::errors::SeasonParseStringError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let mut parts = s.split("_");
let Some(Ok(year)) = parts.next().map(|e|e.parse::<u32>()) else {return Err(Self::Err{the_string:s.to_string()})};
let Some(slot_string) = parts.next() else {return Err(Self::Err{the_string:s.to_string()})};
if parts.next().is_some() {
return Err(Self::Err{the_string:s.to_string()})
}
match slot_string {
"1"=>Ok(Self { year: year, slot: YearSlot::Spring }),
"2"=>Ok(Self { year: year, slot: YearSlot::Autumn }),
_=>return Err(Self::Err{the_string:s.to_string()})
}
}
}
#[derive(Debug,Deserialize)]
pub struct Event {
#[serde(rename="comp")]
pub season:Season,
#[serde(rename="cname")]
pub competition_name:Option<String>,
#[serde(rename="pID")]
pub id:u64,
#[serde(rename="win")]
pub games_won:u64,
#[serde(rename="sum")]
pub games_played:u64,
#[serde(rename="klass")]
pub class_name:String,
#[serde(rename="afd")]
pub division:Division,
#[serde(rename="wie")]
pub selection:Selection,
pub extra:Option<String>,
}
#[derive(Debug,Deserialize)]
pub struct PlayerInfo {
#[serde(rename="BNo")]
bondsnumber:u64,
#[serde(rename="f_naam")]
name:String,
#[serde(rename="geslacht")]
gender:Gender,
#[serde(rename="cat")]
age_category:String,
#[serde(rename="LJ")]
jeugd_licentie:Option<String>,
#[serde(rename="SJ")]
senior_licentie:Option<String>,
}
#[serde_as]
#[derive(Deserialize,Debug)]
pub struct GetInfoResult {
#[serde_as(as = "JsonString")]
pub results:Vec<GetInfoContent>,
#[serde(rename="player")]
#[serde_as(as = "JsonString")]
pub player_info:PlayerInfo
}
#[derive(Debug)]
pub struct EloPerSeason(pub BTreeMap<Season,u32>);
#[derive(Debug)]
pub struct Info {
pub elo:EloPerSeason,
pub results:Vec<Event>,
pub player_info:PlayerInfo
}