parze 0.7.3

A clean, efficient parser combinator
Documentation
use core::iter::FromIterator;

pub trait Chain: Sized {
    type Item;
    type IntoIter: IntoIterator<Item=Self::Item>;
    fn into_iter_chain(self) -> <Self::IntoIter as IntoIterator>::IntoIter;
    fn collect<T: FromIterator<Self::Item>>(self) -> T { self.into_iter_chain().collect() }
    fn as_slice(&self) -> &[Self::Item];
}

impl<T> Chain for Vec<T> {
    type Item = T;
    type IntoIter = <Self as IntoIterator>::IntoIter;
    fn into_iter_chain(self) -> <Self::IntoIter as IntoIterator>::IntoIter { IntoIterator::into_iter(self) }
    fn as_slice(&self) -> &[Self::Item] { &self }
}

pub struct Single<T>([T; 1]);

impl<T> From<T> for Single<T> {
    fn from(item: T) -> Self {
        Self([item])
    }
}

impl<T> IntoIterator for Single<T> {
    type Item = T;
    type IntoIter = SingleIter<T>;

    fn into_iter(self) -> Self::IntoIter {
        let [inner] = self.0;
        SingleIter(Some(inner))
    }
}

impl<T> Chain for Single<T> {
    type Item = T;
    type IntoIter = <Self as IntoIterator>::IntoIter;
    fn into_iter_chain(self) -> <Self::IntoIter as IntoIterator>::IntoIter { IntoIterator::into_iter(self) }
    fn as_slice(&self) -> &[Self::Item] { &self.0 }
}

pub struct SingleIter<T>(Option<T>);

impl<T> Iterator for SingleIter<T> {
    type Item = T;

    fn next(&mut self) -> Option<Self::Item> {
        self.0.take()
    }
}

pub trait IntoChain {
    type Item;
    type Chain: Chain<Item=Self::Item>;

    fn into_chain(self) -> Self::Chain;
}

impl<U: Chain> IntoChain for U {
    type Item = U::Item;
    type Chain = Self;
    fn into_chain(self) -> Self::Chain { self }
}

impl<T> IntoChain for Option<T> {
    type Item = T;
    type Chain = OptionChain<T>;

    fn into_chain(self) -> Self::Chain {
        OptionChain(self.map(|item| [item]))
    }
}

pub struct OptionChain<T>(Option<[T; 1]>);

impl<T> Chain for OptionChain<T> {
    type Item = T;
    type IntoIter = <Self as IntoIterator>::IntoIter;
    fn into_iter_chain(self) -> <Self::IntoIter as IntoIterator>::IntoIter { IntoIterator::into_iter(self) }
    fn as_slice(&self) -> &[Self::Item] {
        self.0.as_ref().map(|arr| arr.as_ref()).unwrap_or(&[])
    }
}

impl<T> IntoIterator for OptionChain<T> {
    type Item = T;
    type IntoIter = SingleIter<T>;

    fn into_iter(self) -> Self::IntoIter {
        self.0.map(|[inner]| {
            SingleIter(Some(inner))
        }).unwrap_or_else(|| SingleIter(None))
    }
}