use std::future::Future;
use crate::AsyncIterator;
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[derive(Debug, Clone)]
pub struct SyncIter<I> {
inner: I,
}
impl<T, I: Iterator<Item = T>> SyncIter<I> {
#[inline]
pub fn new(inner: I) -> Self {
Self { inner }
}
}
impl<T, I: Iterator<Item = T>> AsyncIterator for SyncIter<I> {
type Item = T;
async fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
#[cfg(test)]
#[tokio::test]
async fn test_sync_iter() {
let v = vec![1, 2, 3, 4];
let mut it = SyncIter::new(v.into_iter());
while let Some(val) = it.next().await {
println!("{}", val);
}
}
#[must_use = "iterators are lazy and do nothing unless consumed"]
#[derive(Debug, Clone)]
pub struct AsyncIter<T, I, F>
where
I: Iterator<Item = F>,
F: Future<Output = T>,
{
inner: I,
}
impl<T, F: Future<Output = T>, I: Iterator<Item = F>> AsyncIter<T, I, F> {
#[inline]
pub fn new(inner: I) -> Self {
Self { inner }
}
}
impl<T, F: Future<Output = T>, I: Iterator<Item = F>> AsyncIterator for AsyncIter<T, I, F> {
type Item = T;
async fn next(&mut self) -> Option<Self::Item> {
match self.inner.next() {
Some(t) => Some(t.await),
None => None,
}
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
#[cfg(test)]
#[tokio::test]
async fn test_async_iter() {
let v = vec![1, 2, 3, 4];
async fn do_async(val: u8) -> String {
format!("{} -> {}", val, val + 1)
}
let mut it = AsyncIter::new(v.into_iter().map(do_async));
while let Some(val) = it.next().await {
println!("{}", val);
}
}
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct AsyncOnce<T> {
val: std::option::IntoIter<T>,
}
impl<T> AsyncOnce<T> {
#[inline]
pub fn new(val: T) -> AsyncOnce<T> {
Self {
val: Some(val).into_iter(),
}
}
}
impl<T> AsyncIterator for AsyncOnce<T> {
type Item = T;
async fn next(&mut self) -> Option<Self::Item> {
self.val.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.val.size_hint()
}
}
#[must_use = "iterators are lazy and do nothing unless consumed"]
pub struct AsyncOnceWith<T> {
inner: std::iter::OnceWith<T>,
}
impl<A, T> AsyncOnceWith<T>
where
T: FnOnce() -> A,
{
#[inline]
pub fn new(f: T) -> AsyncOnceWith<T> {
Self {
inner: std::iter::once_with(f),
}
}
}
impl<A, T> AsyncIterator for AsyncOnceWith<T>
where
T: FnOnce() -> A,
{
type Item = A;
async fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.inner.size_hint()
}
}
#[inline]
pub fn once<T>(val: T) -> AsyncOnce<T> {
AsyncOnce::new(val)
}
#[inline]
pub fn once_with<A, F: FnOnce() -> A>(f: F) -> AsyncOnceWith<F> {
AsyncOnceWith::new(f)
}
#[cfg(test)]
#[tokio::test]
async fn test_once_iter() {
let once = AsyncOnce::new(5i32);
assert_eq!(once.collect::<Vec<_>>().await, vec![5]);
let once = AsyncOnceWith::new(|| 5i32);
assert_eq!(once.collect::<Vec<_>>().await, vec![5]);
}