gat_lending_iterator/adapters/
enumerate.rs

1use crate::LendingIterator;
2
3/// A lending iterator that yields the current count and the element during iteration.
4#[derive(Clone, Debug)]
5#[must_use = "iterators are lazy and do nothing unless consumed"]
6pub struct Enumerate<I> {
7    count: usize,
8    iter: I,
9}
10
11impl<I> Enumerate<I> {
12    pub(crate) fn new(iter: I) -> Self {
13        Enumerate { iter, count: 0 }
14    }
15}
16
17impl<I: LendingIterator> LendingIterator for Enumerate<I> {
18    type Item<'a>
19        = (usize, I::Item<'a>)
20    where
21        Self: 'a;
22
23    #[inline]
24    fn next(&mut self) -> Option<Self::Item<'_>> {
25        let item = self.iter.next()?;
26        let count = self.count;
27        self.count += 1;
28        Some((count, item))
29    }
30}
31
32#[cfg(test)]
33mod test {
34    use super::*;
35    use crate::ToLendingIterator;
36
37    // A non-fused iterator for testing that we match std's behavior
38    struct Delay<I> {
39        countdown: usize,
40        iter: I,
41    }
42
43    impl<I> Delay<I> {
44        fn new(countdown: usize, iter: I) -> Self {
45            Delay { countdown, iter }
46        }
47    }
48
49    // Generally we avoid implementing both Iterator and LendingIterator
50    // for the same type. Here in testing the bounds of the arguments
51    // are known not to collide.
52    impl<I: LendingIterator> LendingIterator for Delay<I> {
53        type Item<'a>
54            = I::Item<'a>
55        where
56            Self: 'a;
57        fn next(&mut self) -> Option<Self::Item<'_>> {
58            if self.countdown == 0 {
59                self.iter.next()
60            } else {
61                self.countdown -= 1;
62                None
63            }
64        }
65    }
66
67    impl<I: Iterator> Iterator for Delay<I> {
68        type Item = I::Item;
69        fn next(&mut self) -> Option<Self::Item> {
70            if self.countdown == 0 {
71                self.iter.next()
72            } else {
73                self.countdown -= 1;
74                None
75            }
76        }
77    }
78
79    #[test]
80    fn test() {
81        let first = Some((0, ()));
82        let second = Some((1, ()));
83        let mut delay_iter = Delay::new(1, std::iter::repeat(()).take(2)).enumerate();
84        let mut delay_lending =
85            Delay::new(1, std::iter::repeat(()).into_lending().take(2)).enumerate();
86
87        assert_eq!((None, None), (delay_iter.next(), delay_lending.next()));
88        assert_eq!((first, first), (delay_iter.next(), delay_lending.next()));
89        assert_eq!((second, second), (delay_iter.next(), delay_lending.next()));
90        assert_eq!((None, None), (delay_iter.next(), delay_lending.next()));
91    }
92
93    #[test]
94    fn enumerate_basic() {
95        let mut iter = (10..13).into_lending().enumerate();
96        assert_eq!(iter.next(), Some((0, 10)));
97        assert_eq!(iter.next(), Some((1, 11)));
98        assert_eq!(iter.next(), Some((2, 12)));
99        assert_eq!(iter.next(), None);
100    }
101}