iter-trait 0.3.1

Iter trait for collectons.
Documentation
//! Base iterator traits.

cfg_if! {
    if #[cfg(feature = "std")] {
        use std::iter::FromIterator;
    } else {
        use core::iter::FromIterator;
    }
}

use refs::{Ref, RefMut};

/// A trait for iterable collections which contain data of a given type.
///
/// In most cases, you shouldn't implement this trait directly; instead, you should implement
/// `IntoIterator`, which will in turn implement this trait.
///
/// The only exception is dynamically-sized types, which cannot implement `IntoIterator`. Instead,
/// you should implement this trait to indicate what type of data is inside the collection.
pub trait HasData {
    /// The type of the data inside this collection.
    type Item;
}
impl<T: IntoIterator> HasData for T {
    type Item = <T as IntoIterator>::Item;
}

/// A trait for collections which can be iterated by reference.
///
/// In most cases, you shouldn't implement this trait directly; instead, you should implement
/// `IntoIterator` for a reference of this type, which will in turn implement this trait.
pub trait Iter<'a>: 'a + HasData {
    /// Type of the references to the data in the collection.
    ///
    /// Although this might just be `&'a Item`, it can also be more complicated. For example, an
    /// iterator with `Item = (usize, T)` might use `(usize, &'a T)` for this instead.
    ///
    /// For more information, see the `Ref` trait.
    type ItemRef: Ref<'a, Self::Item>;

    /// Type of the iterator over references.
    type IterRef: Iterator<Item = Self::ItemRef>;

    /// Constructs an iterator over references to the data in this collection.
    fn iter(&'a self) -> Self::IterRef;
}
impl<'a, T: 'a + HasData> Iter<'a> for T
where
    &'a T: IntoIterator,
    <&'a T as IntoIterator>::Item: Ref<'a, T::Item>,
{
    type ItemRef = <&'a Self as IntoIterator>::Item;
    type IterRef = <&'a Self as IntoIterator>::IntoIter;
    fn iter(&'a self) -> Self::IterRef {
        self.into_iter()
    }
}

/// A trait for collections which can be iterated by mutable reference.
///
/// In most cases, you shouldn't implement this trait directly; instead, you should implement
/// `IntoIterator` for a mutable reference of this type, which will in turn implement this trait.
pub trait IterMut<'a>: Iter<'a> {
    /// Type of the mutable references to the data in the collection.
    ///
    /// Although this might just be `&'a Item`, it can also be more complicated. For example, an
    /// iterator with `Item = (usize, T)` might use `(usize, &'a mut T)` for this instead.
    ///
    /// For more information, see the `RefMut` trait.
    type ItemMut: RefMut<'a, Self::Item>;

    /// Type of the iterator over mutable references.
    type IterMut: Iterator<Item = Self::ItemMut>;

    /// Constructs an iterator over mutable references to the data in this collection.
    fn iter_mut(&'a mut self) -> Self::IterMut;
}
impl<'a, T: 'a + Iter<'a>> IterMut<'a> for T
where
    &'a mut T: IntoIterator,
    <&'a mut T as IntoIterator>::Item: RefMut<'a, T::Item>,
{
    type ItemMut = <&'a mut Self as IntoIterator>::Item;
    type IterMut = <&'a mut Self as IntoIterator>::IntoIter;
    fn iter_mut(&'a mut self) -> Self::IterMut {
        self.into_iter()
    }
}

/// A trait for collections which can be converted to and from iterators over data.
pub trait IterOwned
    : HasData
    + IntoIterator<Item = <Self as HasData>::Item>
    + FromIterator<<Self as HasData>::Item>
    + Extend<<Self as HasData>::Item>
{}
impl<T> IterOwned for T
where
    T: HasData,
    T: IntoIterator<Item = <T as HasData>::Item>,
    T: FromIterator<<T as HasData>::Item>,
    T: Extend<<T as HasData>::Item>,
{}