gat_lending_iterator/adapters/
step_by.rs

1use crate::LendingIterator;
2
3/// A lending iterator for stepping lending iterators by a custom amount.
4///
5/// This `struct` is created by the [`step_by`] method on [`LendingIterator`]. See
6/// its documentation for more.
7///
8/// [`LendingIterator`]: crate::LendingIterator
9/// [`step_by`]: crate::LendingIterator::step_by
10#[derive(Clone, Debug)]
11#[must_use = "iterators are lazy and do nothing unless consumed"]
12pub struct StepBy<I> {
13    iter: I,
14    step: usize,
15    first_take: bool,
16}
17
18impl<I> StepBy<I> {
19    #[inline]
20    pub(crate) fn new(iter: I, step: usize) -> StepBy<I> {
21        assert!(step != 0);
22        StepBy {
23            iter,
24            step: step - 1,
25            first_take: true,
26        }
27    }
28}
29
30impl<I> LendingIterator for StepBy<I>
31where
32    I: LendingIterator,
33{
34    type Item<'a>
35        = I::Item<'a>
36    where
37        Self: 'a;
38
39    #[inline]
40    fn next(&mut self) -> Option<Self::Item<'_>> {
41        if self.first_take {
42            self.first_take = false;
43            self.iter.next()
44        } else {
45            self.iter.nth(self.step)
46        }
47    }
48}
49
50#[cfg(test)]
51mod tests {
52    use crate::{LendingIterator, ToLendingIterator};
53
54    fn identity(x: i32) -> i32 {
55        x
56    }
57
58    #[test]
59    fn step_by_basic() {
60        let result: Vec<_> = (0..10)
61            .into_lending()
62            .step_by(3)
63            .map(identity)
64            .into_iter()
65            .collect();
66        assert_eq!(result, vec![0, 3, 6, 9]);
67    }
68}