1use std::str::FromStr;
2
3#[derive(Debug, PartialEq)]
5pub enum QuarterNumber {
6 Q1,
7 Q2,
8 Q3,
9 Q4,
10}
11
12#[derive(Debug, PartialEq, Eq)]
13pub struct ParseQuarterError;
14
15impl FromStr for QuarterNumber {
16 type Err = ParseQuarterError;
17
18 fn from_str(s: &str) -> Result<Self, Self::Err> {
25 match s.to_uppercase().as_str() {
26 "Q1" => Ok(QuarterNumber::Q1),
27 "Q2" => Ok(QuarterNumber::Q2),
28 "Q3" => Ok(QuarterNumber::Q3),
29 "Q4" => Ok(QuarterNumber::Q4),
30 _ => Err(ParseQuarterError),
31 }
32 }
33}
34
35impl TryFrom<u8> for QuarterNumber {
36 type Error = ParseQuarterError;
37
38 fn try_from(value: u8) -> Result<Self, ParseQuarterError> {
45 match value {
46 1 => Ok(QuarterNumber::Q1),
47 2 => Ok(QuarterNumber::Q2),
48 3 => Ok(QuarterNumber::Q3),
49 4 => Ok(QuarterNumber::Q4),
50 _ => Err(ParseQuarterError),
51 }
52 }
53}
54
55#[derive(Debug, PartialEq)]
56pub struct Quarter {
57 pub quarter_number: QuarterNumber,
58 pub year: u16,
59}
60
61impl Quarter {
62 pub fn new(quarter_number: QuarterNumber, year: u16) -> Self {
67 Quarter {
68 quarter_number,
69 year,
70 }
71 }
72
73 pub fn next_quarter(&self) -> Self {
81 match self.quarter_number {
82 QuarterNumber::Q1 => Quarter {
83 year: self.year,
84 quarter_number: QuarterNumber::Q2,
85 },
86 QuarterNumber::Q2 => Quarter {
87 year: self.year,
88 quarter_number: QuarterNumber::Q3,
89 },
90 QuarterNumber::Q3 => Quarter {
91 year: self.year,
92 quarter_number: QuarterNumber::Q4,
93 },
94 QuarterNumber::Q4 => Quarter {
95 year: self.year + 1,
96 quarter_number: QuarterNumber::Q1,
97 },
98 }
99 }
100}
101
102impl FromStr for Quarter {
103 type Err = ParseQuarterError;
104
105 fn from_str(s: &str) -> Result<Self, Self::Err> {
111 let (quarter_number, year) = s.split_once(' ').ok_or(ParseQuarterError)?;
112
113 let quarter_number_fromstr = quarter_number
114 .parse::<QuarterNumber>()
115 .map_err(|_| ParseQuarterError)?;
116 let year_fromstr: u16 = year.parse().map_err(|_| ParseQuarterError)?;
117
118 Ok(Quarter {
119 year: year_fromstr,
120 quarter_number: quarter_number_fromstr,
121 })
122 }
123}