summaryrefslogtreecommitdiffstats
path: root/tokio-futures/src/compat/forward.rs
blob: f343bec493ec8203cb063923f15bba9257850638 (plain)
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
//! Converts an 0.1 `Future` into a `std::future::Future`.
//!
use futures::{Async, Future};

use std::future::Future as StdFuture;
use std::pin::Pin;
use std::task::{Context, Poll as StdPoll};

/// Converts an 0.1 `Future` into a `std::future::Future`.
#[derive(Debug)]
pub struct Compat<T>(T);

pub(crate) fn convert_poll<T, E>(poll: Result<Async<T>, E>) -> StdPoll<Result<T, E>> {
    use futures::Async::{NotReady, Ready};

    match poll {
        Ok(Ready(val)) => StdPoll::Ready(Ok(val)),
        Ok(NotReady) => StdPoll::Pending,
        Err(err) => StdPoll::Ready(Err(err)),
    }
}

pub(crate) fn convert_poll_stream<T, E>(
    poll: Result<Async<Option<T>>, E>,
) -> StdPoll<Option<Result<T, E>>> {
    use futures::Async::{NotReady, Ready};

    match poll {
        Ok(Ready(Some(val))) => StdPoll::Ready(Some(Ok(val))),
        Ok(Ready(None)) => StdPoll::Ready(None),
        Ok(NotReady) => StdPoll::Pending,
        Err(err) => StdPoll::Ready(Some(Err(err))),
    }
}

#[doc(hidden)]
pub trait IntoAwaitable {
    type Awaitable;

    /// Convert `self` into a value that can be used with `await!`.
    fn into_awaitable(self) -> Self::Awaitable;
}

impl<T: Future + Unpin> IntoAwaitable for T {
    type Awaitable = Compat<T>;

    fn into_awaitable(self) -> Self::Awaitable {
        Compat(self)
    }
}

impl<T> StdFuture for Compat<T>
where
    T: Future + Unpin,
{
    type Output = Result<T::Item, T::Error>;

    fn poll(mut self: Pin<&mut Self>, _context: &mut Context) -> StdPoll<Self::Output> {
        use futures::Async::{NotReady, Ready};

        // TODO: wire in cx

        match self.0.poll() {
            Ok(Ready(val)) => StdPoll::Ready(Ok(val)),
            Ok(NotReady) => StdPoll::Pending,
            Err(e) => StdPoll::Ready(Err(e)),
        }
    }
}