1use core::{
2 iter::{DoubleEndedIterator, IntoIterator, Iterator},
3 mem,
4};
5
6use chrono::{Duration, NaiveDate};
7
8use crate::DateRange;
9
10#[derive(Debug, Copy, Clone, PartialEq)]
11pub struct DateRangeIterator {
12 since: NaiveDate,
13 until: NaiveDate,
14}
15
16impl Iterator for DateRangeIterator {
18 type Item = NaiveDate;
19 fn next(&mut self) -> Option<Self::Item> {
20 if self.since <= self.until {
21 let next_front = self.since + Duration::days(1);
22 Some(mem::replace(&mut self.since, next_front))
23 } else {
24 None
25 }
26 }
27}
28impl DoubleEndedIterator for DateRangeIterator {
29 fn next_back(&mut self) -> Option<Self::Item> {
30 if self.since <= self.until {
31 let next_back = self.until - Duration::days(1);
32 Some(mem::replace(&mut self.until, next_back))
33 } else {
34 None
35 }
36 }
37}
38
39impl IntoIterator for DateRange {
40 type Item = NaiveDate;
41
42 type IntoIter = DateRangeIterator;
43
44 fn into_iter(self) -> Self::IntoIter {
45 DateRangeIterator {
46 since: self.since(),
47 until: self.until(),
48 }
49 }
50}
51impl IntoIterator for &DateRange {
52 type Item = NaiveDate;
53
54 type IntoIter = DateRangeIterator;
55
56 fn into_iter(self) -> Self::IntoIter {
57 DateRangeIterator {
58 since: self.since(),
59 until: self.until(),
60 }
61 }
62}
63
64#[cfg(test)]
65mod tests {
66 use super::*;
67
68 #[test]
69 fn simple() {
70 assert_eq!(
71 DateRange::new("2021-08-01".parse().unwrap(), "2021-08-05".parse().unwrap())
72 .unwrap()
73 .into_iter()
74 .collect::<Vec<_>>(),
75 vec![
76 "2021-08-01".parse().unwrap(),
77 "2021-08-02".parse().unwrap(),
78 "2021-08-03".parse().unwrap(),
79 "2021-08-04".parse().unwrap(),
80 "2021-08-05".parse().unwrap(),
81 ]
82 );
83
84 let date_range =
85 &DateRange::new("2021-08-01".parse().unwrap(), "2021-08-05".parse().unwrap()).unwrap();
86 assert_eq!(
87 date_range.into_iter().rev().collect::<Vec<_>>(),
88 vec![
89 "2021-08-05".parse().unwrap(),
90 "2021-08-04".parse().unwrap(),
91 "2021-08-03".parse().unwrap(),
92 "2021-08-02".parse().unwrap(),
93 "2021-08-01".parse().unwrap(),
94 ]
95 );
96
97 let mut iter = DateRangeIterator {
99 since: "2021-08-01".parse().unwrap(),
100 until: "2021-08-05".parse().unwrap(),
101 };
102 assert_eq!(iter.next(), Some("2021-08-01".parse().unwrap()));
103 assert_eq!(iter.next_back(), Some("2021-08-05".parse().unwrap()));
104 assert_eq!(iter.next_back(), Some("2021-08-04".parse().unwrap()));
105 assert_eq!(iter.next(), Some("2021-08-02".parse().unwrap()));
106 assert_eq!(iter.next(), Some("2021-08-03".parse().unwrap()));
107 assert_eq!(iter.next(), None);
108 assert_eq!(iter.next_back(), None);
109 assert_eq!(iter.since, "2021-08-04".parse().unwrap());
110 assert_eq!(iter.until, "2021-08-03".parse().unwrap());
111 }
112}