async_iter_ext/
iter.rs

1use std::vec::IntoIter;
2
3use sync_iter::SyncIter;
4
5pub mod process_result;
6pub mod sync_iter;
7
8pub trait AsyncIterator {
9    type Item;
10
11    fn next_async(&mut self) -> impl Future<Output = Option<Self::Item>>;
12
13    fn sync_iter(&mut self) -> impl Future<Output = SyncIter<IntoIter<Self::Item>>>
14    where
15        Self: Sized,
16    {
17        async move { SyncIter::new(collect_into_vec(self).await.into_iter()) }
18    }
19
20    fn async_size_hint(&self) -> (usize, Option<usize>) {
21        (0, None)
22    }
23
24    fn async_collect<B>(mut self) -> impl Future<Output = B>
25    where
26        Self: Sized,
27        B: FromIterator<Self::Item>,
28    {
29        async move {
30            let items = collect_into_vec(&mut self).await;
31            B::from_iter(items)
32        }
33    }
34}
35
36async fn collect_into_vec<I>(iter: &mut I) -> Vec<I::Item>
37where
38    I: AsyncIterator,
39{
40    let mut items = vec![];
41
42    match iter.async_size_hint() {
43        (_, Some(upper_limit)) => {
44            for _ in 0..upper_limit {
45                if let Some(item) = iter.next_async().await {
46                    items.push(item);
47                }
48            }
49        }
50        _ => {
51            while let Some(item) = iter.next_async().await {
52                items.push(item);
53            }
54        }
55    }
56
57    items
58}
59
60impl<T> AsyncIterator for T
61where
62    T: Iterator + ?Sized,
63{
64    type Item = T::Item;
65
66    async fn next_async(&mut self) -> Option<Self::Item> {
67        self.next()
68    }
69
70    fn async_size_hint(&self) -> (usize, Option<usize>) {
71        self.size_hint()
72    }
73}