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}