use crate::stream::Stream; use core::future::Future; use core::marker::PhantomPinned; use core::pin::Pin; use core::task::{Context, Poll}; use pin_project_lite::pin_project; pin_project! { /// Future returned by the [`fold`](super::StreamExt::fold) method. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] pub struct FoldFuture { #[pin] stream: St, acc: Option, f: F, // Make this future `!Unpin` for compatibility with async trait methods. #[pin] _pin: PhantomPinned, } } impl FoldFuture { pub(super) fn new(stream: St, init: B, f: F) -> Self { Self { stream, acc: Some(init), f, _pin: PhantomPinned, } } } impl Future for FoldFuture where St: Stream, F: FnMut(B, St::Item) -> B, { type Output = B; fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { let mut me = self.project(); loop { let next = ready!(me.stream.as_mut().poll_next(cx)); match next { Some(v) => { let old = me.acc.take().unwrap(); let new = (me.f)(old, v); *me.acc = Some(new); } None => return Poll::Ready(me.acc.take().unwrap()), } } } }