hetseq 0.2.0

Defines traits and types to work with heterogenous sequences
Documentation
use std::marker::Unsize;
use {List, Queue};

pub trait UnsizeRefIterator<I: ?Sized> {
    #[inline]
    fn next(&self) -> Option<(&I, &UnsizeRefIterator<I>)>;
    #[inline]
    fn size(&self) -> usize;
}

pub trait UnsizeRefMutIterator<I: ?Sized>: UnsizeRefIterator<I> {
    #[inline]
    fn next_mut(&mut self) -> Option<(&mut I, &mut UnsizeRefIterator<I>)>;
}

impl<I> UnsizeRefIterator<I> for List<()>
    where I: ?Sized
{
    #[inline]
    fn next(&self) -> Option<(&I, &UnsizeRefIterator<I>)> {
        None
    }
    #[inline]
    fn size(&self) -> usize {
        0
    }
}

impl<I> UnsizeRefMutIterator<I> for List<()>
    where I: ?Sized
{
    #[inline]
    fn next_mut(&mut self) -> Option<(&mut I, &mut UnsizeRefIterator<I>)> {
        None
    }
}

impl<I, H, T> UnsizeRefIterator<I> for List<(H, List<T>)>
    where I: ?Sized,
          H: Unsize<I>,
          List<T>: UnsizeRefIterator<I>,
{
    #[inline]
    fn next(&self) -> Option<(&I, &UnsizeRefIterator<I>)> {
        let List((ref head, ref tail)) = *self;
        Some((head, tail))
    }
    #[inline]
    fn size(&self) -> usize {
        1 + self.tail().size()
    }
}

impl<I, H, T> UnsizeRefMutIterator<I> for List<(H, List<T>)>
    where I: ?Sized,
          H: Unsize<I>,
          List<T>: UnsizeRefMutIterator<I>,
{
    #[inline]
    fn next_mut(&mut self) -> Option<(&mut I, &mut UnsizeRefIterator<I>)> {
        let List((ref mut head, ref mut tail)) = *self;
        Some((head, tail))
    }
}

pub struct UnsizeRefIter<'a, I: 'a + ?Sized>(&'a UnsizeRefIterator<I>);

impl<'a, I: 'a> UnsizeRefIter<'a, I>
    where I: ?Sized
{
    fn new(inner: &'a UnsizeRefIterator<I>) -> Self {
        UnsizeRefIter(inner)
    }
}

impl<'a, I: 'a + ?Sized> Iterator for UnsizeRefIter<'a, I> {
    type Item = &'a I;
    fn next(&mut self) -> Option<&'a I> {
        let UnsizeRefIter(ref mut inner) = *self;
        match inner.next() {
            Some((item, next)) => {
                *inner = next;
                Some(item)
            }
            None => None,
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        (self.0.size(), Some(self.0.size()))
    }
}

pub trait IntoRefIter {
    fn into_ref_iter<I: ?Sized>(&self) -> UnsizeRefIter<I> where Self: UnsizeRefIterator<I> + Sized {
        UnsizeRefIter::new(self)
    }
}

impl<Q> IntoRefIter for Queue<Q> {}
impl<L> IntoRefIter for List<L> {}