1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
//! This crate gives Streams a `reduce` function that is similar to //! [`fold`](https://docs.rs/futures/0.3.4/futures/stream/trait.StreamExt.html#method.fold) //! but without an initial value. The function returns a [`Future`](core::future::Future) //! containing `None` if the stream is empty and `Some(value)` otherwise. //! //! Based on David Tolnay's [`reduce`](https://docs.rs/reduce/0.1.2/reduce/) crate for iterators. //! //! # Examples //! ``` //! use stream_reduce::Reduce; //! use futures::stream; //! //! # futures::executor::block_on( //! async { //! // Reduce a non-empty stream into Some(value) //! let v = vec![1usize, 2, 3, 4, 5]; //! let sum = stream::iter(v).reduce(|a, b| async move { a + b }).await; //! assert_eq!(Some(15), sum); //! //! // Reduce an empty stream into None //! let v = Vec::<usize>::new(); //! let product = stream::iter(v).reduce(|a, b| async move { a * b }).await; //! assert_eq!(None, product); //! } //! # ) //! ``` #![no_std] use core::future::Future; use futures::Stream; mod reducer; pub use reducer::Reducer; pub trait Reduce<T>: Stream { fn reduce<F, Fut>(self, f: F) -> Reducer<Self, T, F, Fut> where Self: Sized, F: FnMut(T, Self::Item) -> Fut, Fut: Future<Output = T>, { Reducer::new(self, f) } } impl<S, T> Reduce<T> for S where S: Stream<Item = T> {}