//! When MSRV is 1.48, replace with `core::future::Ready` and `core::future::ready()`. use core::{ future::Future, pin::Pin, task::{Context, Poll}, }; /// Future for the [`ready`](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 { val: Option, } impl Ready { /// Unwraps the value from this immediately ready future. #[inline] pub fn into_inner(mut self) -> T { self.val.take().unwrap() } } impl Unpin for Ready {} impl Future for Ready { type Output = T; #[inline] fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll { 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); /// ``` pub fn ready(val: T) -> Ready { Ready { val: Some(val) } } /// Create 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)); /// # } /// ``` pub fn ok(val: T) -> Ready> { Ready { val: Some(Ok(val)) } } /// Create 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)); /// # } /// ``` pub fn err(err: E) -> Ready> { Ready { val: Some(Err(err)), } } #[cfg(test)] mod tests { use futures_util::task::noop_waker; use super::*; #[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); } }