diff --git a/src/stream/cycle.rs b/src/stream/cycle.rs new file mode 100644 index 0000000..9438469 --- /dev/null +++ b/src/stream/cycle.rs @@ -0,0 +1,62 @@ +use std::pin::Pin; + +use pin_project_lite::pin_project; + +use crate::stream::Stream; +use crate::task::{Context, Poll}; + +pin_project! { + /// A stream that will repeatedly yield the same list of elements + pub struct Cycle { + source: Vec, + index: usize, + len: usize, + } +} + +impl Stream for Cycle { + type Item = T; + + fn poll_next(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { + let value = self.source[self.index]; + + let next = self.index + 1; + + if next >= self.len { + self.as_mut().index = 0; + } else { + self.as_mut().index = next; + } + + Poll::Ready(Some(value)) + } +} + +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// # async_std::task::block_on(async { +/// # +/// use async_std::prelude::*; +/// use async_std::stream; +/// +/// let mut s = stream::cycle(vec![1,2,3]); +/// +/// assert_eq!(s.next().await, Some(1)); +/// assert_eq!(s.next().await, Some(2)); +/// assert_eq!(s.next().await, Some(3)); +/// assert_eq!(s.next().await, Some(1)); +/// assert_eq!(s.next().await, Some(2)); +/// # +/// # }) +/// ``` +pub fn cycle(source: Vec) -> impl Stream { + let len = source.len(); + Cycle { + source, + index: 0, + len, + } +} diff --git a/src/stream/mod.rs b/src/stream/mod.rs index 07eecf2..449c484 100644 --- a/src/stream/mod.rs +++ b/src/stream/mod.rs @@ -300,6 +300,7 @@ //! [`take`]: trait.Stream.html#method.take //! [`min`]: trait.Stream.html#method.min +pub use cycle::{cycle, Cycle}; pub use empty::{empty, Empty}; pub use from_fn::{from_fn, FromFn}; pub use from_iter::{from_iter, FromIter}; @@ -312,6 +313,7 @@ pub use stream::{ pub(crate) mod stream; +mod cycle; mod empty; mod from_fn; mod from_iter; diff --git a/src/stream/stream/cycle.rs b/src/stream/stream/cycle.rs deleted file mode 100644 index 7ed0774..0000000 --- a/src/stream/stream/cycle.rs +++ /dev/null @@ -1,38 +0,0 @@ -use std::pin::Pin; - -use pin_project_lite::pin_project; - -use crate::stream::Stream; -use crate::task::{Context, Poll}; - -/// A stream that will repeatedly yield the same list of elements -pub struct Cycle { - source: Vec, - index: usize, -} - -impl Stream for Cycle { - type Item = T; - - fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - Poll::Pending - } -} - -/// # Examples -/// -/// Basic usage: -/// -/// ``` -/// # fn main() -> std::io::Result<()> { async_std::task::block_on(async { -/// -/// let values = vec![1,2,3]; -/// -/// # Ok(()) }) } -///``` -fn cycle(values: Vec) -> impl Stream { - Cycle { - source: values, - index: 0, - } -} diff --git a/src/stream/stream/mod.rs b/src/stream/stream/mod.rs index 4a845f1..d46ae87 100644 --- a/src/stream/stream/mod.rs +++ b/src/stream/stream/mod.rs @@ -24,10 +24,11 @@ mod all; mod any; mod chain; -mod enumerate; +mod cmp; mod cycle; mod copied; mod cmp; +mod enumerate; mod eq; mod filter; mod filter_map;