resume_generator/
date_range.rs1crate::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}