enumerate_base/
lib.rs

1#![doc = include_str!("../README.md")]
2#![no_std]
3
4use core::{iter::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    fn enumerate_base(self, base: N) -> EnumerateBase<Self, N> {
97        EnumerateBase { iter: self, base }
98    }
99}
100
101impl<T, N> IteratorEnumerateBaseExt<N> for T
102where EnumerateBase<T, N>: Iterator
103{}