gat_lending_iterator/to_lending/
windows.rs

1use crate::LendingIterator;
2
3/// A lending iterator over windows.
4///
5/// This `struct` is created by the [`windows`] method on [`ToLendingIterator`]. See
6/// its documentation for more.
7///
8/// [`ToLendingIterator`]: crate::ToLendingIterator
9/// [`windows`]: crate::ToLendingIterator::windows
10#[derive(Clone)]
11pub struct Windows<I: Iterator> {
12    iter: I,
13    size: usize,
14    buf: Vec<I::Item>,
15}
16
17impl<I: Iterator> Windows<I> {
18    pub(crate) fn new(mut iter: I, size: usize) -> Self {
19        let buf = iter.by_ref().take(size - 1).collect();
20        Self { iter, size, buf }
21    }
22}
23
24impl<I: Iterator> LendingIterator for Windows<I> {
25    type Item<'a>
26        = &'a [I::Item]
27    where
28        Self: 'a;
29
30    fn next(&mut self) -> Option<Self::Item<'_>> {
31        self.iter.next().map(|next| {
32            if self.buf.len() == self.size * 2 - 1 {
33                self.buf.drain(..self.size);
34            }
35            self.buf.push(next);
36            &self.buf[self.buf.len() - self.size..]
37        })
38    }
39}
40
41#[cfg(test)]
42mod tests {
43    use crate::{LendingIterator, ToLendingIterator};
44
45    fn to_vec_i32(w: &[i32]) -> Vec<i32> {
46        w.to_vec()
47    }
48
49    #[test]
50    fn windows_basic() {
51        let result: Vec<_> = (0..5).windows(3).map(to_vec_i32).into_iter().collect();
52        assert_eq!(result, vec![vec![0, 1, 2], vec![1, 2, 3], vec![2, 3, 4]]);
53    }
54
55    #[test]
56    fn windows_size_one() {
57        let result: Vec<_> = (0..3).windows(1).map(to_vec_i32).into_iter().collect();
58        assert_eq!(result, vec![vec![0], vec![1], vec![2]]);
59    }
60
61    #[test]
62    fn windows_larger_than_iterator() {
63        let mut iter = (0..3).windows(5);
64        assert_eq!(iter.next(), None);
65    }
66
67    #[test]
68    fn windows_empty_iterator() {
69        let mut iter = std::iter::empty::<i32>().windows(3);
70        assert_eq!(iter.next(), None);
71    }
72}