slist 0.1.2

Algebraic lists with statically determined size that live on stack.
Documentation
use crate::{Either, List, Slist, SlistSum, Void};

use core::iter::IntoIterator;

impl<T, N, S> IntoIterator for List<T, N>
where
    N: Slist<T, Filter = S>,
    S: SlistSum<T, Next = N>,
    Either<Self, Either<N, S>>: Iterator<Item = T>,
{
    type Item = T;
    type IntoIter = Either<Self, Either<N, S>>;

    fn into_iter(self) -> Self::IntoIter {
        self.filter(|_| true)
    }
}
    
impl<T, N, S> Iterator for Either<List<T, N>, Either<N, S>>
where
    N: Slist<T, Filter = S>,
    S: SlistSum<T, Next = N> + Default,
    Either<N, S>: Iterator<Item = T>,
{
    type Item = T;

    #[inline]
    fn next(&mut self) -> Option<Self::Item> {
        match self {
            Either::Left(_) => {
                let owned = core::mem::take(self);
                if let Either::Left(list) = owned {
                    *self = Either::Right(Either::Left(list.tail));
                    Some(list.head)
                } else {
                    unreachable!();
                }
            }
            Either::Right(ref mut r) => r.next(),
        }
    }
}

impl<T> Iterator for Either<List<T, ()>, Either<(), Void>>
{
    type Item = T;

    #[inline]
    fn next(&mut self) -> Option<Self::Item> {
        match self {
            Either::Left(_) => {
                let owned = core::mem::take(self);
                if let Either::Left(list) = owned {
                    Some(list.head)
                } else {
                    unreachable!();
                }
            }
            Either::Right(_) => None,
        }
    }
}