use std::pin::Pin; use crate::prelude::*; use crate::stream::{FromStream, IntoStream}; impl FromStream> for Result where V: FromStream, { /// Takes each element in the stream: if it is an `Err`, no further /// elements are taken, and the `Err` is returned. Should no `Err` /// occur, a container with the values of each `Result` is returned. /// /// # Examples /// /// ``` /// # fn main() { async_std::task::block_on(async { /// # /// use async_std::prelude::*; /// use async_std::stream; /// /// let v = stream::from_iter(vec![1, 2]); /// let res: Result, &'static str> = v.map(|x: u32| /// x.checked_add(1).ok_or("Overflow!") /// ).collect().await; /// assert_eq!(res, Ok(vec![2, 3])); /// # /// # }) } /// ``` #[inline] fn from_stream<'a, S: IntoStream> + 'a>( stream: S, ) -> Pin + 'a>> { let stream = stream.into_stream(); Box::pin(async move { // Using `take_while` here because it is able to stop the stream early // if a failure occurs let mut is_error = false; let mut found_error = None; let out: V = stream .take_while(|elem| { // Stop processing the stream on `Err` !is_error && (elem.is_ok() || { is_error = true; // Capture first `Err` true }) }) .filter_map(|elem| match elem { Ok(value) => Some(value), Err(err) => { found_error = Some(err); None } }) .collect() .await; if is_error { Err(found_error.unwrap()) } else { Ok(out) } }) } }