asynciter 0.1.0

Asynchronous iterator.
Documentation
use std::{fmt::Debug, future::Future};

use crate::AsyncIterator;

#[must_use = "iterators are lazy and do nothing unless consumed"]
#[derive(Clone)]
pub struct Map<I, F> {
    inner: I,
    func: F,
}

impl<I: AsyncIterator + Debug, F> Debug for Map<I, F> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("Map").field("inner", &self.inner).finish()
    }
}

impl<I, F> Map<I, F> {
    #[inline]
    pub fn new(inner: I, func: F) -> Map<I, F> {
        Self { inner, func }
    }
}

impl<I: AsyncIterator, F, B> AsyncIterator for Map<I, F>
where
    F: FnMut(I::Item) -> B,
{
    type Item = B;

    async fn next(&mut self) -> Option<Self::Item> {
        match self.inner.next().await {
            Some(t) => Some((self.func)(t)),
            None => None,
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.inner.size_hint()
    }
}

#[must_use = "iterators are lazy and do nothing unless consumed"]
#[derive(Clone)]
pub struct AsyncMap<I, F> {
    inner: I,
    func: F,
}

impl<I: AsyncIterator + Debug, F> Debug for AsyncMap<I, F> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("AsyncMap").field("inner", &self.inner).finish()
    }
}

impl<I, F> AsyncMap<I, F> {
    #[inline]
    pub fn new(inner: I, func: F) -> AsyncMap<I, F> {
        Self { inner, func }
    }
}

impl<I: AsyncIterator, F, B, O> AsyncIterator for AsyncMap<I, F>
where
    F: FnMut(I::Item) -> O,
    O: Future<Output = B>,
{
    type Item = B;

    async fn next(&mut self) -> Option<Self::Item> {
        match self.inner.next().await {
            Some(t) => Some((self.func)(t).await),
            None => None,
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.inner.size_hint()
    }
}