futures_util/stream/iter_result.rs
1use futures_core::{Async, Poll, Stream};
2use futures_core::task;
3
4/// A stream which is just a shim over an underlying instance of `Iterator`.
5///
6/// This stream will never block and is always ready.
7#[derive(Debug)]
8#[must_use = "streams do nothing unless polled"]
9pub struct IterResult<I> {
10 iter: I,
11}
12
13/// Converts an `Iterator` over `Result`s into a `Stream` which is always ready
14/// to yield the next value.
15///
16/// Iterators in Rust don't express the ability to block, so this adapter simply
17/// always calls `iter.next()` and returns that.
18///
19/// ```rust
20/// # extern crate futures;
21/// # extern crate futures_executor;
22/// use futures::prelude::*;
23/// use futures::stream;
24/// use futures_executor::block_on;
25///
26/// # fn main() {
27/// let mut stream = stream::iter_result(vec![Ok(17), Err(false), Ok(19)]);
28/// let (item, stream) = block_on(stream.next()).unwrap();
29/// assert_eq!(Some(17), item);
30/// let (err, stream) = block_on(stream.next()).unwrap_err();
31/// assert_eq!(false, err);
32/// let (item, stream) = block_on(stream.next()).unwrap();
33/// assert_eq!(Some(19), item);
34/// let (item, _) = block_on(stream.next()).unwrap();
35/// assert_eq!(None, item);
36/// # }
37/// ```
38pub fn iter_result<J, T, E>(i: J) -> IterResult<J::IntoIter>
39where
40 J: IntoIterator<Item = Result<T, E>>,
41{
42 IterResult {
43 iter: i.into_iter(),
44 }
45}
46
47impl<I, T, E> Stream for IterResult<I>
48where
49 I: Iterator<Item = Result<T, E>>,
50{
51 type Item = T;
52 type Error = E;
53
54 fn poll_next(&mut self, _: &mut task::Context) -> Poll<Option<T>, E> {
55 match self.iter.next() {
56 Some(Ok(e)) => Ok(Async::Ready(Some(e))),
57 Some(Err(e)) => Err(e),
58 None => Ok(Async::Ready(None)),
59 }
60 }
61}