gat_lending_iterator/adapters/
scan.rs1use crate::LendingIterator;
2use core::fmt;
3
4#[derive(Clone)]
12#[must_use = "iterators are lazy and do nothing unless consumed"]
13pub struct Scan<I, St, F> {
14 iter: I,
15 f: F,
16 state: St,
17}
18
19impl<I, St, F> Scan<I, St, F> {
20 pub(crate) fn new(iter: I, state: St, f: F) -> Self {
21 Self { iter, f, state }
22 }
23}
24
25impl<I: fmt::Debug, St: fmt::Debug, F> fmt::Debug for Scan<I, St, F> {
26 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
27 f.debug_struct("Scan")
28 .field("iter", &self.iter)
29 .field("state", &self.state)
30 .finish_non_exhaustive()
31 }
32}
33
34impl<I, St, F, B> LendingIterator for Scan<I, St, F>
35where
36 I: LendingIterator,
37 F: for<'a> FnMut(&'a mut St, I::Item<'a>) -> Option<B>,
38{
39 type Item<'a>
40 = B
41 where
42 Self: 'a;
43
44 #[inline]
45 fn next(&mut self) -> Option<Self::Item<'_>> {
46 let item = self.iter.next()?;
47 (self.f)(&mut self.state, item)
48 }
49
50 #[inline]
51 fn size_hint(&self) -> (usize, Option<usize>) {
52 let (_, upper) = self.iter.size_hint();
53 (0, upper)
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use crate::{LendingIterator, ToLendingIterator};
60
61 #[test]
62 fn scan_basic() {
63 let mut result = Vec::new();
64 (1..=5)
65 .into_lending()
66 .scan(0, |state: &mut i32, x| {
67 *state += x;
68 Some(*state)
69 })
70 .for_each(|x| result.push(x));
71 assert_eq!(result, vec![1, 3, 6, 10, 15]);
72 }
73
74 #[test]
75 fn scan_early_termination() {
76 let mut result = Vec::new();
77 (1..=10)
78 .into_lending()
79 .scan(0, |state: &mut i32, x| {
80 *state += x;
81 if *state > 10 {
82 None
83 } else {
84 Some(*state)
85 }
86 })
87 .for_each(|x| result.push(x));
88 assert_eq!(result, vec![1, 3, 6, 10]);
89 }
90}