async_iter_ext/
iter.rs

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