coc_rs/models/
season.rs

1use serde::{Deserialize, Serialize};
2use time::Month;
3
4#[derive(Debug, Clone)]
5pub enum SeasonError {
6    InvalidSeason,
7    ParseFailed(String),
8}
9
10#[derive(Debug, Clone)]
11pub struct SeasonBuilder {
12    season: Season,
13}
14
15#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct Season {
17    #[serde(rename = "id")]
18    id: String,
19    #[serde(skip_deserializing, skip_serializing)]
20    year: i32,
21    #[serde(skip_deserializing, skip_serializing, default = "Season::default_month")]
22    month: Month,
23}
24
25#[derive(Debug, Serialize, Deserialize, Clone)]
26#[serde(rename_all = "camelCase")]
27pub struct PreviousSeasonData {
28    pub id: String,
29    pub rank: i32,
30    pub trophies: i32,
31}
32
33#[derive(Debug, Serialize, Deserialize, Clone)]
34#[serde(rename_all = "camelCase")]
35pub struct BestSeasonData {
36    pub id: String,
37    pub rank: i32,
38    pub trophies: i32,
39}
40
41#[derive(Debug, Serialize, Deserialize, Clone)]
42#[serde(rename_all = "camelCase")]
43pub struct PreviousVersusSeasonData {
44    pub id: String,
45    pub rank: i32,
46    pub trophies: i32,
47}
48
49#[derive(Debug, Serialize, Deserialize, Clone)]
50#[serde(rename_all = "camelCase")]
51pub struct BestVersusSeasonData {
52    pub id: String,
53    pub rank: i32,
54    pub trophies: i32,
55}
56
57#[derive(Debug, Serialize, Deserialize, Clone)]
58#[serde(rename_all = "camelCase")]
59pub struct CurrentSeasonData {
60    pub id: Option<String>,
61    pub rank: Option<i32>,
62    pub trophies: i32,
63}
64
65impl From<std::num::ParseIntError> for SeasonError {
66    fn from(err: std::num::ParseIntError) -> Self {
67        Self::ParseFailed(err.to_string())
68    }
69}
70
71impl SeasonBuilder {
72    const fn new() -> Self {
73        Self { season: Season { id: String::new(), year: 2015, month: Month::July } }
74    }
75
76    #[must_use]
77    pub const fn year(mut self, year: i32) -> Self {
78        self.season.year = year;
79        self
80    }
81
82    #[must_use]
83    pub const fn month(mut self, month: Month) -> Self {
84        self.season.month = month;
85        self
86    }
87
88    #[must_use]
89    pub fn build(mut self) -> Season {
90        self.season.id = format!("{}-{:02}", self.season.year, self.season.month as i32);
91        self.season
92    }
93}
94
95impl Season {
96    #[must_use]
97    pub const fn default_month() -> Month {
98        Month::July
99    }
100
101    #[must_use]
102    pub const fn builder() -> SeasonBuilder {
103        SeasonBuilder::new()
104    }
105}
106
107impl std::str::FromStr for Season {
108    type Err = SeasonError;
109
110    fn from_str(season: &str) -> Result<Self, Self::Err> {
111        let mut season_split = season.split('-');
112        Ok(Self {
113            id: season.to_string(),
114            year: season_split.next().ok_or(SeasonError::InvalidSeason)?.parse()?,
115            month: Month::try_from(
116                season_split.next().ok_or(SeasonError::InvalidSeason)?.parse::<u8>()?,
117            )
118            .unwrap(),
119        })
120    }
121}
122
123impl std::fmt::Display for Season {
124    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
125        let mut season_split = self.id.split('-');
126        let year = season_split.next().unwrap().parse::<i32>().unwrap();
127        let month = Month::try_from(season_split.next().unwrap().parse::<u8>().unwrap()).unwrap();
128        write!(f, "{year}-{:02}", month as i32)
129    }
130}