use core::mem; use core::pin::Pin; use crate::stream::Stream; use crate::task::{Context, Poll}; use pin_project_lite::pin_project; /// Creates a new stream where to produce each new element a closure is called with the previous /// value. /// /// # Examples /// /// ``` /// # fn main() { async_std::task::block_on(async { /// # /// use async_std::prelude::*; /// use async_std::stream; /// /// let mut s = stream::successors(Some(22), |&val| Some(val + 1)); /// /// assert_eq!(s.next().await, Some(22)); /// assert_eq!(s.next().await, Some(23)); /// assert_eq!(s.next().await, Some(24)); /// assert_eq!(s.next().await, Some(25)); /// /// # /// # }) } /// ``` #[cfg(feature = "unstable")] #[cfg_attr(feature = "docs", doc(cfg(unstable)))] pub fn successors(first: Option, succ: F) -> Successors where F: FnMut(&T) -> Option, { Successors { succ, slot: first } } pin_project! { /// A stream that yields elements by calling an async closure with the previous value as an /// argument /// /// This stream is constructed by [`successors`] function /// /// [`successors`]: fn.succssors.html #[cfg(feature = "unstable")] #[cfg_attr(feature = "docs", doc(cfg(unstable)))] #[derive(Debug)] pub struct Successors where F: FnMut(&T) -> Option { succ: F, slot: Option, } } impl Stream for Successors where F: FnMut(&T) -> Option, { type Item = T; fn poll_next(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { let this = self.project(); if this.slot.is_none() { return Poll::Ready(None); } let mut next = (this.succ)(&this.slot.as_ref().unwrap()); // 'swapping' here means 'slot' will hold the next value and next will be th one from the previous iteration mem::swap(this.slot, &mut next); Poll::Ready(next) } }