srctrait_note/
date.rs

1use chrono::{Duration, Local, NaiveDate};
2use com::chrono::DateRelativeParsing;
3use srctrait_common_chronox::{DateDisplay, DateTimeFormat};
4use crate::*;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub struct Date(NaiveDate);
8
9impl Date {
10    pub fn now() -> Self {
11        Self(Local::now().date_naive())
12    }
13
14    /// Parse a string following either Y-m-d or Y/m/d formats, with year and
15    /// month being optional.
16    pub fn from(&self, when: &str) -> Result<Self> {
17        if when == "yesterday" {
18            Ok(Self(self.0 - Duration::days(1)))
19        } else if let Some(date) = self.0.parse_relative_date(when) {
20            Ok(Self(date))
21        } else {
22            Err(Error::Date(when.to_string()))
23        }
24    }
25
26    pub fn naive(&self) -> &NaiveDate {
27        &self.0
28    }
29
30    pub fn display(&self, format: DateTimeFormat) -> DateDisplay {
31        DateDisplay::new(self.0, format)
32    }
33}
34
35
36#[cfg(test)]
37mod tests {
38    use super::*;
39
40    #[test]
41    fn test_date_from() {
42        let date = Date(NaiveDate::from_ymd_opt(1974, 5, 6).unwrap());
43
44        assert_eq!(
45            &NaiveDate::from_ymd_opt(1974, 5, 5).unwrap(),
46            date.from("yesterday").unwrap().naive());
47
48        assert_eq!(
49            &NaiveDate::from_ymd_opt(1974, 4, 5).unwrap(),
50            date.from("04-05").unwrap().naive());
51
52        assert_eq!(
53            &NaiveDate::from_ymd_opt(1974, 4, 5).unwrap(),
54            date.from("4/5").unwrap().naive());
55
56        assert_eq!(
57            &NaiveDate::from_ymd_opt(1974, 5, 10).unwrap(),
58            date.from("10").unwrap().naive());
59    }
60}