srctrait_note/
date.rs

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