enumerate_base/
lib.rs

1#![doc = include_str!("../README.md")]
2#![no_std]
3
4use core::{iter::{self, FusedIterator}, ops::Add};
5
6#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Default, Hash)]
7pub struct EnumerateBase<I, N> {
8    iter: I,
9    base: N,
10}
11
12impl<I, N, T> Iterator for EnumerateBase<I, N>
13where I: Iterator<Item = (N, T)>,
14      N: Add + Copy,
15{
16    type Item = (N::Output, T);
17
18    fn next(&mut self) -> Option<Self::Item> {
19        self.iter.next().map(|(n, elem)| (n + self.base, elem))
20    }
21
22    fn nth(&mut self, n: usize) -> Option<Self::Item> {
23        self.iter.nth(n).map(|(n, elem)| (n + self.base, elem))
24    }
25
26    fn fold<B, F>(self, init: B, mut f: F) -> B
27    where Self: Sized,
28          F: FnMut(B, Self::Item) -> B,
29    {
30        self.iter.fold(init, |acc, (n, elem)| {
31            f(acc, (n + self.base, elem))
32        })
33    }
34
35    fn size_hint(&self) -> (usize, Option<usize>) {
36        self.iter.size_hint()
37    }
38}
39
40impl<I, N, T> DoubleEndedIterator for EnumerateBase<I, N>
41where I: DoubleEndedIterator<Item = (N, T)>,
42      N: Add + Copy,
43{
44    fn next_back(&mut self) -> Option<Self::Item> {
45        self.iter.next_back().map(|(n, elem)| (n + self.base, elem))
46    }
47
48    fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
49        self.iter.nth_back(n).map(|(n, elem)| (n + self.base, elem))
50    }
51
52    fn rfold<B, F>(self, init: B, mut f: F) -> B
53    where Self: Sized,
54          F: FnMut(B, Self::Item) -> B,
55    {
56        self.iter.rfold(init, |acc, (n, elem)| {
57            f(acc, (n + self.base, elem))
58        })
59    }
60}
61
62impl<I, N, T> FusedIterator for EnumerateBase<I, N>
63where I: FusedIterator<Item = (N, T)>,
64      N: Add + Copy,
65{
66}
67
68impl<I, N, T> ExactSizeIterator for EnumerateBase<I, N>
69where I: ExactSizeIterator<Item = (N, T)>,
70      N: Add + Copy,
71{
72}
73
74/// Extend methods for all [`Iterator`]
75pub trait IteratorEnumerateBaseExt<N>: Sized
76where EnumerateBase<Self, N>: Iterator,
77{
78    /// Plus the count of [`Iterator::enumerate`] by `base`
79    ///
80    /// Similar to `self.map(|(n, elem)| (n + base, elem))`
81    ///
82    /// # Example
83    ///
84    /// ```
85    /// use crate::enumerate_base::IteratorEnumerateBaseExt as _;
86    /// let arr = ['a', 'b', 'c', 'd'];
87    /// let iter = arr.into_iter().enumerate().enumerate_base(2);
88    ///
89    /// assert_eq!(iter.collect::<Vec<_>>(), vec![
90    ///     (2, 'a'),
91    ///     (3, 'b'),
92    ///     (4, 'c'),
93    ///     (5, 'd'),
94    /// ]);
95    /// ```
96    #[inline]
97    fn enumerate_base(self, base: N) -> EnumerateBase<Self, N> {
98        EnumerateBase { iter: self, base }
99    }
100}
101
102impl<T, N> IteratorEnumerateBaseExt<N> for T
103where EnumerateBase<T, N>: Iterator
104{}
105
106/// Extend methods for all [`iter::Enumerate`]
107pub trait EnumerateBaseExt: Sized {
108    /// Plus the count of [`Iterator::enumerate`] by `base`
109    ///
110    /// Similar to `self.map(|(n, elem)| (n + base, elem))`
111    ///
112    /// # Example
113    ///
114    /// ```
115    /// use crate::enumerate_base::EnumerateBaseExt as _;
116    /// let arr = ['a', 'b', 'c', 'd'];
117    /// let iter = arr.into_iter().enumerate().base(2);
118    ///
119    /// assert_eq!(iter.collect::<Vec<_>>(), vec![
120    ///     (2, 'a'),
121    ///     (3, 'b'),
122    ///     (4, 'c'),
123    ///     (5, 'd'),
124    /// ]);
125    /// ```
126    fn base(self, base: usize) -> EnumerateBase<Self, usize>;
127}
128
129impl<I: Iterator> EnumerateBaseExt for iter::Enumerate<I> {
130    #[inline]
131    fn base(self, base: usize) -> EnumerateBase<Self, usize> {
132        self.enumerate_base(base)
133    }
134}