futures_util/future/
or_else.rs

1use futures_core::{Future, IntoFuture, Poll};
2use futures_core::task;
3use super::chain::Chain;
4
5/// Future for the `or_else` combinator, chaining a computation onto the end of
6/// a future which fails with an error.
7///
8/// This is created by the `Future::or_else` method.
9#[derive(Debug)]
10#[must_use = "futures do nothing unless polled"]
11pub struct OrElse<A, B, F> where A: Future, B: IntoFuture {
12    state: Chain<A, B::Future, F>,
13}
14
15pub fn new<A, B, F>(future: A, f: F) -> OrElse<A, B, F>
16    where A: Future,
17          B: IntoFuture<Item=A::Item>,
18{
19    OrElse {
20        state: Chain::new(future, f),
21    }
22}
23
24impl<A, B, F> Future for OrElse<A, B, F>
25    where A: Future,
26          B: IntoFuture<Item=A::Item>,
27          F: FnOnce(A::Error) -> B,
28{
29    type Item = B::Item;
30    type Error = B::Error;
31
32    fn poll(&mut self, cx: &mut task::Context) -> Poll<B::Item, B::Error> {
33        self.state.poll(cx, |a, f| {
34            match a {
35                Ok(item) => Ok(Ok(item)),
36                Err(e) => Ok(Err(f(e).into_future()))
37            }
38        })
39    }
40}