wonfy_tools/util/iter/
windows_iter.rs1use std::collections::VecDeque;
2
3pub trait IterWindows: Iterator {
4 fn windows(self, size: usize) -> Windows<Self>
5 where
6 Self: Sized + Iterator,
7 Self::Item: Clone,
8 {
9 Windows::new(self, size)
10 }
11}
12
13#[must_use = "iterator adaptors are lazy and do nothing unless consumed"]
14#[derive(Clone, Debug)]
15pub struct Windows<I>
16where
17 I: Iterator,
18{
19 iter: I,
20 size: usize,
21 last: Option<VecDeque<I::Item>>,
22}
23
24impl<I> Windows<I>
25where
26 I: Iterator,
27{
28 pub fn new(iter: I, size: usize) -> Self {
29 Self {
30 iter,
31 size,
32 last: None,
33 }
34 }
35}
36
37impl<I> Iterator for Windows<I>
38where
39 I: Iterator,
40 I::Item: Clone,
41{
42 type Item = VecDeque<I::Item>;
43
44 fn next(&mut self) -> Option<Self::Item> {
45 if let Some(new) = self.iter.next() {
46 if let Some(ref mut last) = self.last {
47 last.pop_back();
48 last.push_front(new);
49 Some(last.clone())
50 } else {
51 use std::iter::once;
52 let iter = once(new).chain(&mut self.iter).take(self.size);
53 self.last = Some(iter.collect());
54 self.last.clone()
55 }
56 } else {
57 None
58 }
59 }
60
61 fn size_hint(&self) -> (usize, Option<usize>) {
62 let mut sh = self.iter.size_hint();
63
64 if self.last.is_none() {
65 let (mut low, mut hi) = sh;
66 low = low.saturating_sub(self.size);
67 hi = hi.map(|elt| elt.saturating_sub(self.size));
68 sh = (low, hi)
69 }
70
71 sh
72 }
73}
74
75impl<T> IterWindows for T where T: Iterator + ?Sized {}