#
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);
        }
    }