use core::{
iter::{DoubleEndedIterator, IntoIterator, Iterator},
mem,
};
use chrono::{Duration, NaiveDate};
use crate::DateRange;
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct DateRangeIterator {
since: NaiveDate,
until: NaiveDate,
}
impl Iterator for DateRangeIterator {
type Item = NaiveDate;
fn next(&mut self) -> Option<Self::Item> {
if self.since <= self.until {
let next_front = self.since + Duration::days(1);
Some(mem::replace(&mut self.since, next_front))
} else {
None
}
}
}
impl DoubleEndedIterator for DateRangeIterator {
fn next_back(&mut self) -> Option<Self::Item> {
if self.since <= self.until {
let next_back = self.until - Duration::days(1);
Some(mem::replace(&mut self.until, next_back))
} else {
None
}
}
}
impl IntoIterator for DateRange {
type Item = NaiveDate;
type IntoIter = DateRangeIterator;
fn into_iter(self) -> Self::IntoIter {
DateRangeIterator {
since: self.since(),
until: self.until(),
}
}
}
impl IntoIterator for &DateRange {
type Item = NaiveDate;
type IntoIter = DateRangeIterator;
fn into_iter(self) -> Self::IntoIter {
DateRangeIterator {
since: self.since(),
until: self.until(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn simple() {
assert_eq!(
DateRange::new("2021-08-01".parse().unwrap(), "2021-08-05".parse().unwrap())
.unwrap()
.into_iter()
.collect::<Vec<_>>(),
vec![
"2021-08-01".parse().unwrap(),
"2021-08-02".parse().unwrap(),
"2021-08-03".parse().unwrap(),
"2021-08-04".parse().unwrap(),
"2021-08-05".parse().unwrap(),
]
);
let date_range =
&DateRange::new("2021-08-01".parse().unwrap(), "2021-08-05".parse().unwrap()).unwrap();
assert_eq!(
date_range.into_iter().rev().collect::<Vec<_>>(),
vec![
"2021-08-05".parse().unwrap(),
"2021-08-04".parse().unwrap(),
"2021-08-03".parse().unwrap(),
"2021-08-02".parse().unwrap(),
"2021-08-01".parse().unwrap(),
]
);
let mut iter = DateRangeIterator {
since: "2021-08-01".parse().unwrap(),
until: "2021-08-05".parse().unwrap(),
};
assert_eq!(iter.next(), Some("2021-08-01".parse().unwrap()));
assert_eq!(iter.next_back(), Some("2021-08-05".parse().unwrap()));
assert_eq!(iter.next_back(), Some("2021-08-04".parse().unwrap()));
assert_eq!(iter.next(), Some("2021-08-02".parse().unwrap()));
assert_eq!(iter.next(), Some("2021-08-03".parse().unwrap()));
assert_eq!(iter.next(), None);
assert_eq!(iter.next_back(), None);
assert_eq!(iter.since, "2021-08-04".parse().unwrap());
assert_eq!(iter.until, "2021-08-03".parse().unwrap());
}
}