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> = (usize, I::Item<'a>) where Self: 'a;
19
20    #[inline]
21    fn next(&mut self) -> Option<Self::Item<'_>> {
22        let item = self.iter.next()?;
23        let count = self.count;
24        self.count += 1;
25        Some((count, item))
26    }
27}
28
29#[cfg(test)]
30mod test {
31    use super::*;
32    use crate::ToLendingIterator;
33
34    // A non-fused iterator for testing that we match std's behavior
35    struct Delay<I> {
36        countdown: usize,
37        iter: I,
38    }
39
40    impl<I> Delay<I> {
41        fn new(countdown: usize, iter: I) -> Self {
42            Delay { countdown, iter }
43        }
44    }
45
46    // Generally we avoid implementing both Iterator and LendingIterator
47    // for the same type. Here in testing the bounds of the arguments
48    // are known not to collide.
49    impl<I: LendingIterator> LendingIterator for Delay<I> {
50        type Item<'a> = I::Item<'a> where Self: 'a;
51        fn next(&mut self) -> Option<Self::Item<'_>> {
52            if self.countdown == 0 {
53                self.iter.next()
54            } else {
55                self.countdown -= 1;
56                None
57            }
58        }
59    }
60
61    impl<I: Iterator> Iterator for Delay<I> {
62        type Item = I::Item;
63        fn next(&mut self) -> Option<Self::Item> {
64            if self.countdown == 0 {
65                self.iter.next()
66            } else {
67                self.countdown -= 1;
68                None
69            }
70        }
71    }
72
73    #[test]
74    fn test() {
75        let first = Some((0, ()));
76        let second = Some((1, ()));
77        let mut delay_iter = Delay::new(1, std::iter::repeat(()).take(2)).enumerate();
78        let mut delay_lending =
79            Delay::new(1, std::iter::repeat(()).into_lending().take(2)).enumerate();
80
81        assert_eq!((None, None), (delay_iter.next(), delay_lending.next()));
82        assert_eq!((first, first), (delay_iter.next(), delay_lending.next()));
83        assert_eq!((second, second), (delay_iter.next(), delay_lending.next()));
84        assert_eq!((None, None), (delay_iter.next(), delay_lending.next()));
85    }
86}