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 TakeWhile<I, P> {
    iter: I,
    flag: bool,
    predicate: P,
}

impl<I, P> TakeWhile<I, P> {
    pub fn new(iter: I, predicate: P) -> TakeWhile<I, P> {
        TakeWhile {
            iter,
            flag: false,
            predicate,
        }
    }
}

impl<I: Debug, P> Debug for TakeWhile<I, P> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("TakeWhile")
            .field("flag", &self.flag)
            .field("iter", &self.iter)
            .finish()
    }
}

impl<I: AsyncIterator, P> AsyncIterator for TakeWhile<I, P>
where
    P: FnMut(&I::Item) -> bool,
{
    type Item = I::Item;

    #[inline]
    async fn next(&mut self) -> Option<I::Item> {
        if self.flag {
            None
        } else {
            let x = self.iter.next().await?;
            if (self.predicate)(&x) {
                Some(x)
            } else {
                self.flag = true;
                None
            }
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        if self.flag {
            (0, Some(0))
        } else {
            let (_, upper) = self.iter.size_hint();
            (0, upper) // can't know a lower bound, due to the predicate
        }
    }
}

#[must_use = "iterators are lazy and do nothing unless consumed"]
#[derive(Clone)]
pub struct AsyncTakeWhile<I, P> {
    iter: I,
    flag: bool,
    predicate: P,
}

impl<I, P> AsyncTakeWhile<I, P> {
    pub fn new(iter: I, predicate: P) -> AsyncTakeWhile<I, P> {
        AsyncTakeWhile {
            iter,
            flag: false,
            predicate,
        }
    }
}

impl<I: Debug, P> Debug for AsyncTakeWhile<I, P> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("AsyncTakeWhile")
            .field("flag", &self.flag)
            .field("iter", &self.iter)
            .finish()
    }
}

impl<I: AsyncIterator, P, F> AsyncIterator for AsyncTakeWhile<I, P>
where
    P: FnMut(&I::Item) -> F,
    F: Future<Output = bool>,
{
    type Item = I::Item;

    #[inline]
    async fn next(&mut self) -> Option<I::Item> {
        if self.flag {
            None
        } else {
            let x = self.iter.next().await?;
            if (self.predicate)(&x).await {
                Some(x)
            } else {
                self.flag = true;
                None
            }
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        if self.flag {
            (0, Some(0))
        } else {
            let (_, upper) = self.iter.size_hint();
            (0, upper) // can't know a lower bound, due to the predicate
        }
    }
}