1use std::fmt::{Display, Error, Formatter};
4use std::str::FromStr;
5
6#[cfg(feature = "hoi4")]
7use crate::game::Game;
8use crate::token::Token;
9
10#[derive(Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq)]
11pub struct Date {
12 year: i16,
13 month: i8,
14 day: i8,
15 #[cfg(feature = "hoi4")]
16 hour: i8,
17}
18
19impl Date {
20 pub fn new(year: i16, month: i8, day: i8) -> Self {
21 Date {
22 year,
23 month,
24 day,
25 #[cfg(feature = "hoi4")]
26 hour: 1,
27 }
28 }
29}
30
31impl FromStr for Date {
32 type Err = Error;
33
34 fn from_str(s: &str) -> Result<Self, Self::Err> {
35 let s = s.trim_end();
37
38 let mut splits = s.split('.');
39 let year = splits.next().ok_or(Error)?;
40 let month = splits.next().unwrap_or("1");
41 let mut day = splits.next().unwrap_or("1");
42 #[cfg(feature = "hoi4")]
43 let mut hour = splits.next().unwrap_or("1");
44 if let Some(next) = splits.next() {
46 if !next.is_empty() {
47 return Err(Error);
48 }
49 }
50 if day.is_empty() {
51 day = "1";
52 }
53 #[cfg(feature = "hoi4")]
54 if hour.is_empty() {
55 hour = "1";
56 }
57 Ok(Date {
58 year: year.parse().map_err(|_| Error)?,
59 month: month.parse().map_err(|_| Error)?,
60 day: day.parse().map_err(|_| Error)?,
61 #[cfg(feature = "hoi4")]
62 hour: hour.parse().map_err(|_| Error)?,
63 })
64 }
65}
66
67impl TryFrom<&Token> for Date {
68 type Error = Error;
69
70 fn try_from(value: &Token) -> Result<Self, Self::Error> {
71 value.as_str().parse()
72 }
73}
74
75impl Display for Date {
76 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
77 #[cfg(feature = "hoi4")]
78 if Game::is_hoi4() {
79 return write!(f, "{}.{}.{}.{}", self.year, self.month, self.day, self.hour);
80 }
81 write!(f, "{}.{}.{}", self.year, self.month, self.day)
82 }
83}