use crate::Enum;
use core::iter::FusedIterator;
pub fn iter_each<T: Enum>() -> IterEachFrom<T> {
IterEachFrom(T::first())
}
pub fn iter_each_from<T: Enum>(x: T) -> IterEachFrom<T> {
IterEachFrom(Some(x))
}
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[derive(Debug, Clone)]
pub struct IterEachFrom<T>(Option<T>);
impl<T: Enum> Iterator for IterEachFrom<T> {
type Item = T;
#[inline]
fn next(&mut self) -> Option<Self::Item> {
let this = self.0.take()?;
self.0 = this.succ();
Some(this)
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
let Some(this) = &self.0 else {
return (0, Some(0));
};
match T::count_from(this) {
Some(c) => (c.get(), Some(c.get())),
None => (usize::MAX, None),
}
}
#[inline]
fn count(self) -> usize
where
Self: Sized,
{
self.0.map_or(0, |this| {
T::count_from(&this).expect("count overflow").get()
})
}
#[inline]
fn last(self) -> Option<Self::Item> {
self.0?;
T::last()
}
fn fold<B, F>(self, init: B, f: F) -> B
where
F: FnMut(B, Self::Item) -> B,
{
match self.0 {
Some(this) => T::fold_each_from(&this, init, f),
None => init,
}
}
}
impl<T: Enum> FusedIterator for IterEachFrom<T> {}