asynciter/iterimpl/
scan.rs

1use std::{fmt::Debug, future::Future};
2
3use crate::AsyncIterator;
4
5#[must_use = "iterators are lazy and do nothing unless consumed"]
6#[derive(Clone)]
7pub struct Scan<I, St, F> {
8    iter: I,
9    f: F,
10    state: St,
11}
12
13impl<I, St, F> Scan<I, St, F> {
14    pub fn new(iter: I, state: St, f: F) -> Self {
15        Self { iter, state, f }
16    }
17}
18
19impl<I: Debug, St: Debug, F> Debug for Scan<I, St, F> {
20    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21        f.debug_struct("Scan")
22            .field("iter", &self.iter)
23            .field("state", &self.state)
24            .finish()
25    }
26}
27
28impl<B, I, St, F> AsyncIterator for Scan<I, St, F>
29where
30    I: AsyncIterator,
31    F: FnMut(&mut St, I::Item) -> Option<B>,
32{
33    type Item = B;
34
35    #[inline]
36    async fn next(&mut self) -> Option<B> {
37        let a = self.iter.next().await?;
38        (self.f)(&mut self.state, a)
39    }
40
41    #[inline]
42    fn size_hint(&self) -> (usize, Option<usize>) {
43        let (_, upper) = self.iter.size_hint();
44        (0, upper) // can't know a lower bound, due to the scan function
45    }
46}
47
48#[must_use = "iterators are lazy and do nothing unless consumed"]
49#[derive(Clone)]
50pub struct AsyncScan<I, St, F> {
51    iter: I,
52    f: F,
53    state: St,
54}
55
56impl<I, St, F> AsyncScan<I, St, F> {
57    pub fn new(iter: I, state: St, f: F) -> Self {
58        Self { iter, state, f }
59    }
60}
61
62impl<I: Debug, St: Debug, F> Debug for AsyncScan<I, St, F> {
63    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64        f.debug_struct("Scan")
65            .field("iter", &self.iter)
66            .field("state", &self.state)
67            .finish()
68    }
69}
70
71impl<B, I, St, F, O> AsyncIterator for AsyncScan<I, St, F>
72where
73    I: AsyncIterator,
74    F: FnMut(&mut St, I::Item) -> O,
75    O: Future<Output = Option<B>>,
76{
77    type Item = B;
78
79    #[inline]
80    async fn next(&mut self) -> Option<B> {
81        let a = self.iter.next().await?;
82        (self.f)(&mut self.state, a).await
83    }
84
85    #[inline]
86    fn size_hint(&self) -> (usize, Option<usize>) {
87        let (_, upper) = self.iter.size_hint();
88        (0, upper) // can't know a lower bound, due to the scan function
89    }
90}