actix_utils/future/
ready.rs

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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
//! When `core::future::Ready` has a `into_inner()` method, this can be deprecated.

use core::{
    future::Future,
    pin::Pin,
    task::{Context, Poll},
};

/// Future for the [`ready`] function.
///
/// Panic will occur if polled more than once.
///
/// # Examples
/// ```
/// use actix_utils::future::ready;
///
/// // async
/// # async fn run() {
/// let a = ready(1);
/// assert_eq!(a.await, 1);
/// # }
///
/// // sync
/// let a = ready(1);
/// assert_eq!(a.into_inner(), 1);
/// ```
#[derive(Debug, Clone)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Ready<T> {
    val: Option<T>,
}

impl<T> Ready<T> {
    /// Unwraps the value from this immediately ready future.
    #[inline]
    pub fn into_inner(mut self) -> T {
        self.val.take().unwrap()
    }
}

impl<T> Unpin for Ready<T> {}

impl<T> Future for Ready<T> {
    type Output = T;

    #[inline]
    fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<T> {
        let val = self.val.take().expect("Ready polled after completion");
        Poll::Ready(val)
    }
}

/// Creates a future that is immediately ready with a value.
///
/// # Examples
/// ```no_run
/// use actix_utils::future::ready;
///
/// # async fn run() {
/// let a = ready(1);
/// assert_eq!(a.await, 1);
/// # }
///
/// // sync
/// let a = ready(1);
/// assert_eq!(a.into_inner(), 1);
/// ```
#[inline]
pub fn ready<T>(val: T) -> Ready<T> {
    Ready { val: Some(val) }
}

/// Creates a future that is immediately ready with a success value.
///
/// # Examples
/// ```no_run
/// use actix_utils::future::ok;
///
/// # async fn run() {
/// let a = ok::<_, ()>(1);
/// assert_eq!(a.await, Ok(1));
/// # }
/// ```
#[inline]
pub fn ok<T, E>(val: T) -> Ready<Result<T, E>> {
    Ready { val: Some(Ok(val)) }
}

/// Creates a future that is immediately ready with an error value.
///
/// # Examples
/// ```no_run
/// use actix_utils::future::err;
///
/// # async fn run() {
/// let a = err::<(), _>(1);
/// assert_eq!(a.await, Err(1));
/// # }
/// ```
#[inline]
pub fn err<T, E>(err: E) -> Ready<Result<T, E>> {
    Ready {
        val: Some(Err(err)),
    }
}

#[cfg(test)]
mod tests {
    use std::rc::Rc;

    use futures_util::task::noop_waker;
    use static_assertions::{assert_impl_all, assert_not_impl_any};

    use super::*;

    assert_impl_all!(Ready<()>: Send, Sync, Unpin, Clone);
    assert_impl_all!(Ready<Rc<()>>: Unpin, Clone);
    assert_not_impl_any!(Ready<Rc<()>>: Send, Sync);

    #[test]
    #[should_panic]
    fn multiple_poll_panics() {
        let waker = noop_waker();
        let mut cx = Context::from_waker(&waker);

        let mut ready = ready(1);
        assert_eq!(Pin::new(&mut ready).poll(&mut cx), Poll::Ready(1));

        // panic!
        let _ = Pin::new(&mut ready).poll(&mut cx);
    }
}