1/// Represents a time span between two dates.
2pub struct TimeSpan {
3 start: time::Date,
4 end: time::Date,
5}
6
7/// Iterates over a time span by included days.
8pub struct DayIterator<'a> {
9 cur: &'a TimeSpan,
10 off: i64, // offset in days
11}
12
13impl<'a> Iterator for DayIterator<'a> {
14 type Item = time::Date;
15
16 fn next(&mut self) -> Option<Self::Item> {
17 let cur = &self.cur;
18 match cur.start.checked_add(time::Duration::days(self.off)) {
19 Some(ndate) => {
20 if ndate > cur.end {
21 return None;
22 }
23 self.off += 1;
24 return Some(ndate);
25 }
26 None => return None,
27 }
28 }
29}
30
31impl TimeSpan {
32 pub fn new(day: time::Date, back: time::Duration, forward: time::Duration) -> Option<Self> {
33 let start = day.checked_sub(back)?;
34 let end = day.checked_add(forward)?;
35
36 Some(TimeSpan { start, end })
37 }
38
39 /// Iterate over all days in the given time span.
40 pub fn iter(&self) -> DayIterator {
41 return DayIterator { cur: self, off: 0 };
42 }
43}
44
45////////////////////////////////////////////////////////////////////////
46
47#[cfg(test)]
48mod tests {
49 use super::*;
50 use time::macros::date;
51
52 #[test]
53 fn iterator() {
54 let d = date!(1980 - 03 - 20);
55 let t = TimeSpan::new(d, time::Duration::days(0), time::Duration::days(1)).unwrap();
56
57 let mut it: DayIterator = t.iter();
58 assert_eq!(it.next(), Some(date!(1980 - 03 - 20)));
59 assert_eq!(it.next(), Some(date!(1980 - 03 - 21)));
60 assert_eq!(it.next(), None);
61 }
62}