resume_generator/
date_range.rs

1crate::ix!();
2
3#[derive(Debug,Clone)]
4pub struct DateRange {
5    start: NaiveDate,
6    end:   Option<NaiveDate>,
7}
8
9impl DateRange {
10    pub fn builder() -> DateRangeBuilder {
11        DateRangeBuilder::default()
12    }
13
14    pub fn start(&self) -> NaiveDate {
15        self.start
16    }
17
18    pub fn end(&self) -> Option<NaiveDate> {
19        self.end
20    }
21}
22
23#[derive(Default)]
24pub struct DateRangeBuilder {
25    start: Option<NaiveDate>,
26    end:   Option<NaiveDate>,
27}
28
29impl DateRangeBuilder {
30    pub fn start(mut self, start: NaiveDate) -> Self {
31        self.start = Some(start);
32        self
33    }
34
35    pub fn end(mut self, end: Option<NaiveDate>) -> Self {
36        self.end = end;
37        self
38    }
39
40    pub fn build(self) -> DateRange {
41        DateRange {
42            start: self.start.expect("Start date is required"),
43            end: self.end,
44        }
45    }
46}
47
48pub fn format_date_range(dates: &DateRange) -> String {
49    let end_date = match dates.end() {
50        Some(date) => date.to_string(),
51        None => "Present".to_string(),
52    };
53    format!("{} - {}", dates.start(), end_date)
54}
55
56pub fn date(year: i32, month: u32, day: u32) -> Result<NaiveDate, ResumeBuilderError> {
57    Ok(NaiveDate::from_ymd_opt(year, month, day).ok_or(ResumeBuilderError::CouldNotParseDate)?)
58}
59
60#[macro_export]
61macro_rules! date {
62    ($year:expr, $month:expr, $day:expr) => {
63        date($year, $month, $day).unwrap()
64    };
65}
66
67#[macro_export]
68macro_rules! date_range {
69    (start => $start:expr) => {
70        DateRange::builder()
71            .start(date!($start.0, $start.1, $start.2))
72            .end(None)
73            .build()
74    };
75    (start => $start:expr, end => $end:expr) => {
76        DateRange::builder()
77            .start(date!($start.0, $start.1, $start.2))
78            .end(Some(date!($end.0, $end.1, $end.2)))
79            .build()
80    };
81}