enumerate-base 0.1.1

Plus the count of Iterator::enumerate by base
Documentation
#![doc = include_str!("../README.md")]
#![no_std]

use core::{iter::{self, FusedIterator}, ops::Add};

#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Default, Hash)]
pub struct EnumerateBase<I, N> {
    iter: I,
    base: N,
}

impl<I, N, T> Iterator for EnumerateBase<I, N>
where I: Iterator<Item = (N, T)>,
      N: Add + Copy,
{
    type Item = (N::Output, T);

    fn next(&mut self) -> Option<Self::Item> {
        self.iter.next().map(|(n, elem)| (n + self.base, elem))
    }

    fn nth(&mut self, n: usize) -> Option<Self::Item> {
        self.iter.nth(n).map(|(n, elem)| (n + self.base, elem))
    }

    fn fold<B, F>(self, init: B, mut f: F) -> B
    where Self: Sized,
          F: FnMut(B, Self::Item) -> B,
    {
        self.iter.fold(init, |acc, (n, elem)| {
            f(acc, (n + self.base, elem))
        })
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

impl<I, N, T> DoubleEndedIterator for EnumerateBase<I, N>
where I: DoubleEndedIterator<Item = (N, T)>,
      N: Add + Copy,
{
    fn next_back(&mut self) -> Option<Self::Item> {
        self.iter.next_back().map(|(n, elem)| (n + self.base, elem))
    }

    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
        self.iter.nth_back(n).map(|(n, elem)| (n + self.base, elem))
    }

    fn rfold<B, F>(self, init: B, mut f: F) -> B
    where Self: Sized,
          F: FnMut(B, Self::Item) -> B,
    {
        self.iter.rfold(init, |acc, (n, elem)| {
            f(acc, (n + self.base, elem))
        })
    }
}

impl<I, N, T> FusedIterator for EnumerateBase<I, N>
where I: FusedIterator<Item = (N, T)>,
      N: Add + Copy,
{
}

impl<I, N, T> ExactSizeIterator for EnumerateBase<I, N>
where I: ExactSizeIterator<Item = (N, T)>,
      N: Add + Copy,
{
}

/// Extend methods for all [`Iterator`]
pub trait IteratorEnumerateBaseExt<N>: Sized
where EnumerateBase<Self, N>: Iterator,
{
    /// Plus the count of [`Iterator::enumerate`] by `base`
    ///
    /// Similar to `self.map(|(n, elem)| (n + base, elem))`
    ///
    /// # Example
    ///
    /// ```
    /// use crate::enumerate_base::IteratorEnumerateBaseExt as _;
    /// let arr = ['a', 'b', 'c', 'd'];
    /// let iter = arr.into_iter().enumerate().enumerate_base(2);
    ///
    /// assert_eq!(iter.collect::<Vec<_>>(), vec![
    ///     (2, 'a'),
    ///     (3, 'b'),
    ///     (4, 'c'),
    ///     (5, 'd'),
    /// ]);
    /// ```
    #[inline]
    fn enumerate_base(self, base: N) -> EnumerateBase<Self, N> {
        EnumerateBase { iter: self, base }
    }
}

impl<T, N> IteratorEnumerateBaseExt<N> for T
where EnumerateBase<T, N>: Iterator
{}

/// Extend methods for all [`iter::Enumerate`]
pub trait EnumerateBaseExt: Sized {
    /// Plus the count of [`Iterator::enumerate`] by `base`
    ///
    /// Similar to `self.map(|(n, elem)| (n + base, elem))`
    ///
    /// # Example
    ///
    /// ```
    /// use crate::enumerate_base::EnumerateBaseExt as _;
    /// let arr = ['a', 'b', 'c', 'd'];
    /// let iter = arr.into_iter().enumerate().base(2);
    ///
    /// assert_eq!(iter.collect::<Vec<_>>(), vec![
    ///     (2, 'a'),
    ///     (3, 'b'),
    ///     (4, 'c'),
    ///     (5, 'd'),
    /// ]);
    /// ```
    fn base(self, base: usize) -> EnumerateBase<Self, usize>;
}

impl<I: Iterator> EnumerateBaseExt for iter::Enumerate<I> {
    #[inline]
    fn base(self, base: usize) -> EnumerateBase<Self, usize> {
        self.enumerate_base(base)
    }
}