gat_lending_iterator/to_lending/
windows.rs1use crate::LendingIterator;
2
3#[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}