advent_of_code_client/
problem.rs1use std::fmt::Display;
2
3use derive_getters::{Dissolve, Getters};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Getters, Dissolve)]
22pub struct Problem {
23 year: Year,
24 day: Day,
25}
26
27impl Problem {
28 pub const fn new(year: Year, day: Day) -> Self {
30 Self { year, day }
31 }
32}
33
34impl From<(Year, Day)> for Problem {
35 fn from((year, day): (Year, Day)) -> Self {
36 Self { year, day }
37 }
38}
39
40impl TryFrom<(u16, u8)> for Problem {
41 type Error = String;
42
43 fn try_from((year, day): (u16, u8)) -> Result<Self, Self::Error> {
44 let Some(year) = Year::from_repr(year) else {
45 return Err(format!(
46 "Invalid year provided. Valid years are from 2015 to {}",
47 Year::max()
48 ));
49 };
50 if day == 0 || day > 25 {
51 return Err("Invalid day provided. Valid days are from 1 to 25".to_string());
52 }
53
54 Ok(Self { year, day })
55 }
56}
57
58impl Display for Problem {
59 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60 write!(f, "{:?}/{}", self.year, self.day)
61 }
62}
63
64#[derive(Copy, Clone, Debug, PartialEq, Eq, clap::ValueEnum, strum::FromRepr)]
66#[cfg_attr(test, derive(fake::Dummy))]
67#[repr(u16)]
68pub enum Year {
69 Y2016 = 2016,
70 Y2017 = 2017,
71 Y2018 = 2018,
72 Y2019 = 2019,
73 Y2020 = 2020,
74 Y2021 = 2021,
75 Y2022 = 2022,
76 Y2023 = 2023,
77}
78
79impl Year {
80 pub const fn as_int(self) -> u16 {
81 self as u16
82 }
83
84 pub const fn max() -> Year {
85 Self::Y2023
86 }
87}
88
89impl Display for Year {
90 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
91 write!(f, "{:?}", self)
92 }
93}
94
95pub type Day = u8;
97
98#[derive(Debug, PartialEq, Eq, PartialOrd, Clone, Copy)]
100pub enum Level {
101 A = 1,
102 B = 2,
103}
104
105impl Level {
106 pub fn as_int(self) -> u8 {
107 self as u8
108 }
109}
110
111impl From<u8> for Level {
112 fn from(value: u8) -> Self {
113 match value {
114 1 => Self::A,
115 2 => Self::B,
116 _ => panic!("Cannot convert value {} to Level", value),
117 }
118 }
119}
120
121#[cfg(test)]
122mod test {
123 use std::convert::Into;
124
125 use fake::{Fake, Faker};
126
127 use super::*;
128
129 #[test]
130 fn from_year_and_day_tuple() {
131 let year: Year = Faker.fake();
132 let day: Day = (1..=25).fake();
133 assert_eq!(Into::<Problem>::into((year, day)), Problem { year, day });
134 }
135}