futures_util/future/
recover.rs

1use core::marker::PhantomData;
2
3use futures_core::{Future, Poll, Async};
4use futures_core::task;
5
6/// Future for the `recover` combinator, handling errors by converting them into
7/// an `Item`, compatible with any error type of the caller's choosing.
8#[must_use = "futures do nothing unless polled"]
9#[derive(Debug)]
10pub struct Recover<A, E, F> {
11    inner: A,
12    f: Option<F>,
13    err: PhantomData<E>,
14}
15
16pub fn new<A, E, F>(future: A, f: F) -> Recover<A, E, F>
17    where A: Future
18{
19    Recover { inner: future, f: Some(f), err: PhantomData }
20}
21
22impl<A, E, F> Future for Recover<A, E, F>
23    where A: Future,
24          F: FnOnce(A::Error) -> A::Item,
25{
26    type Item = A::Item;
27    type Error = E;
28
29    fn poll(&mut self, cx: &mut task::Context) -> Poll<A::Item, E> {
30        match self.inner.poll(cx) {
31            Err(e) => Ok(Async::Ready((self.f.take().expect("Polled future::Recover after completion"))(e))),
32            Ok(x) => Ok(x),
33        }
34    }
35}