use crate::{Date, Month, MonthShape};
use core::iter::FusedIterator;
use core::ops::RangeInclusive;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Days {
month_shape: MonthShape,
inner: RangeInclusive<u32>,
}
impl Days {
pub(crate) const fn new(month_shape: MonthShape) -> Self {
Days {
month_shape,
inner: 1..=(month_shape.len()),
}
}
}
impl Iterator for Days {
type Item = u32;
fn next(&mut self) -> Option<u32> {
self.month_shape.nth_day(self.inner.next()?)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl FusedIterator for Days {}
impl ExactSizeIterator for Days {}
impl DoubleEndedIterator for Days {
fn next_back(&mut self) -> Option<u32> {
self.month_shape.nth_day(self.inner.next_back()?)
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Dates {
month_shape: MonthShape,
inner: RangeInclusive<u32>,
}
impl Dates {
pub(crate) const fn new(month_shape: MonthShape) -> Self {
Dates {
month_shape,
inner: 1..=(month_shape.len()),
}
}
}
impl Iterator for Dates {
type Item = Date;
fn next(&mut self) -> Option<Date> {
self.month_shape.nth_date(self.inner.next()?)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
impl FusedIterator for Dates {}
impl ExactSizeIterator for Dates {}
impl DoubleEndedIterator for Dates {
fn next_back(&mut self) -> Option<Date> {
self.month_shape.nth_date(self.inner.next_back()?)
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Later {
date: Option<Date>,
}
impl Later {
pub(crate) const fn new(date: Date) -> Later {
Later { date: Some(date) }
}
}
impl Iterator for Later {
type Item = Date;
fn next(&mut self) -> Option<Date> {
self.date = self.date.and_then(|d| d.succ());
self.date
}
}
impl FusedIterator for Later {}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Earlier {
date: Option<Date>,
}
impl Earlier {
pub(crate) const fn new(date: Date) -> Earlier {
Earlier { date: Some(date) }
}
}
impl Iterator for Earlier {
type Item = Date;
fn next(&mut self) -> Option<Date> {
self.date = self.date.and_then(|d| d.pred());
self.date
}
}
impl FusedIterator for Earlier {}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct AndLater {
date: Option<Date>,
}
impl AndLater {
pub(crate) const fn new(date: Date) -> AndLater {
AndLater { date: Some(date) }
}
}
impl Iterator for AndLater {
type Item = Date;
fn next(&mut self) -> Option<Date> {
let date = self.date?;
self.date = date.succ();
Some(date)
}
}
impl FusedIterator for AndLater {}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct AndEarlier {
date: Option<Date>,
}
impl AndEarlier {
pub(crate) const fn new(date: Date) -> AndEarlier {
AndEarlier { date: Some(date) }
}
}
impl Iterator for AndEarlier {
type Item = Date;
fn next(&mut self) -> Option<Date> {
let date = self.date?;
self.date = date.pred();
Some(date)
}
}
impl FusedIterator for AndEarlier {}
#[derive(Clone, Debug, Hash, Eq, PartialEq)]
pub struct MonthIter(RangeInclusive<u16>);
impl MonthIter {
pub const fn new() -> MonthIter {
MonthIter(1..=12)
}
}
impl Default for MonthIter {
fn default() -> MonthIter {
MonthIter::new()
}
}
impl Iterator for MonthIter {
type Item = Month;
fn next(&mut self) -> Option<Month> {
Some(
u32::from(self.0.next()?)
.try_into()
.expect("inner iterator item should be valid month number"),
)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}
impl FusedIterator for MonthIter {}
impl ExactSizeIterator for MonthIter {}
impl DoubleEndedIterator for MonthIter {
fn next_back(&mut self) -> Option<Month> {
Some(
u32::from(self.0.next_back()?)
.try_into()
.expect("inner iterator item should be valid month number"),
)
}
}