For users looking at documentation through IDE popups, this gives them relevant information rather than the generic trait documentation wording “Performs the conversion”. For users reading the documentation for a specific type for any reason, this informs them when the conversion may allocate or copy significant memory versus when it is always a move or cheap copy. Notes on specific cases: * The new documentation for `From<T> for T` explains that it is not a conversion at all. * Also documented `impl<T, U> Into<U> for T where U: From<T>`, the other central blanket implementation of conversion. * I did not add documentation to conversions of a specific error type to a more general error type. * I did not add documentation to unstable code. This change was prepared by searching for the text "From<... for" and so may have missed some cases that for whatever reason did not match. I also looked for `Into` impls but did not find any worth documenting by the above criteria.
321 lines
10 KiB
Rust
321 lines
10 KiB
Rust
#![stable(feature = "futures_api", since = "1.36.0")]
|
|
|
|
use crate::convert;
|
|
use crate::ops::{self, ControlFlow};
|
|
use crate::result::Result;
|
|
use crate::task::Ready;
|
|
|
|
/// Indicates whether a value is available or if the current task has been
|
|
/// scheduled to receive a wakeup instead.
|
|
#[must_use = "this `Poll` may be a `Pending` variant, which should be handled"]
|
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
|
#[stable(feature = "futures_api", since = "1.36.0")]
|
|
pub enum Poll<T> {
|
|
/// Represents that a value is immediately ready.
|
|
#[lang = "Ready"]
|
|
#[stable(feature = "futures_api", since = "1.36.0")]
|
|
Ready(#[stable(feature = "futures_api", since = "1.36.0")] T),
|
|
|
|
/// Represents that a value is not ready yet.
|
|
///
|
|
/// When a function returns `Pending`, the function *must* also
|
|
/// ensure that the current task is scheduled to be awoken when
|
|
/// progress can be made.
|
|
#[lang = "Pending"]
|
|
#[stable(feature = "futures_api", since = "1.36.0")]
|
|
Pending,
|
|
}
|
|
|
|
impl<T> Poll<T> {
|
|
/// Maps a `Poll<T>` to `Poll<U>` by applying a function to a contained value.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// Converts a <code>Poll<[String]></code> into a <code>Poll<[usize]></code>, consuming
|
|
/// the original:
|
|
///
|
|
/// [String]: ../../std/string/struct.String.html "String"
|
|
/// ```
|
|
/// # use core::task::Poll;
|
|
/// let poll_some_string = Poll::Ready(String::from("Hello, World!"));
|
|
/// // `Poll::map` takes self *by value*, consuming `poll_some_string`
|
|
/// let poll_some_len = poll_some_string.map(|s| s.len());
|
|
///
|
|
/// assert_eq!(poll_some_len, Poll::Ready(13));
|
|
/// ```
|
|
#[stable(feature = "futures_api", since = "1.36.0")]
|
|
pub fn map<U, F>(self, f: F) -> Poll<U>
|
|
where
|
|
F: FnOnce(T) -> U,
|
|
{
|
|
match self {
|
|
Poll::Ready(t) => Poll::Ready(f(t)),
|
|
Poll::Pending => Poll::Pending,
|
|
}
|
|
}
|
|
|
|
/// Returns `true` if the poll is a [`Poll::Ready`] value.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// # use core::task::Poll;
|
|
/// let x: Poll<u32> = Poll::Ready(2);
|
|
/// assert_eq!(x.is_ready(), true);
|
|
///
|
|
/// let x: Poll<u32> = Poll::Pending;
|
|
/// assert_eq!(x.is_ready(), false);
|
|
/// ```
|
|
#[inline]
|
|
#[rustc_const_stable(feature = "const_poll", since = "1.49.0")]
|
|
#[stable(feature = "futures_api", since = "1.36.0")]
|
|
pub const fn is_ready(&self) -> bool {
|
|
matches!(*self, Poll::Ready(_))
|
|
}
|
|
|
|
/// Returns `true` if the poll is a [`Pending`] value.
|
|
///
|
|
/// [`Pending`]: Poll::Pending
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// # use core::task::Poll;
|
|
/// let x: Poll<u32> = Poll::Ready(2);
|
|
/// assert_eq!(x.is_pending(), false);
|
|
///
|
|
/// let x: Poll<u32> = Poll::Pending;
|
|
/// assert_eq!(x.is_pending(), true);
|
|
/// ```
|
|
#[inline]
|
|
#[rustc_const_stable(feature = "const_poll", since = "1.49.0")]
|
|
#[stable(feature = "futures_api", since = "1.36.0")]
|
|
pub const fn is_pending(&self) -> bool {
|
|
!self.is_ready()
|
|
}
|
|
|
|
/// Extracts the successful type of a [`Poll<T>`].
|
|
///
|
|
/// When combined with the `?` operator, this function will
|
|
/// propagate any [`Poll::Pending`] values to the caller, and
|
|
/// extract the `T` from [`Poll::Ready`].
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```rust
|
|
/// #![feature(poll_ready)]
|
|
///
|
|
/// use std::task::{Context, Poll};
|
|
/// use std::future::{self, Future};
|
|
/// use std::pin::Pin;
|
|
///
|
|
/// pub fn do_poll(cx: &mut Context<'_>) -> Poll<()> {
|
|
/// let mut fut = future::ready(42);
|
|
/// let fut = Pin::new(&mut fut);
|
|
///
|
|
/// let num = fut.poll(cx).ready()?;
|
|
/// # drop(num);
|
|
/// // ... use num
|
|
///
|
|
/// Poll::Ready(())
|
|
/// }
|
|
/// ```
|
|
#[inline]
|
|
#[unstable(feature = "poll_ready", issue = "89780")]
|
|
pub fn ready(self) -> Ready<T> {
|
|
Ready(self)
|
|
}
|
|
}
|
|
|
|
impl<T, E> Poll<Result<T, E>> {
|
|
/// Maps a `Poll<Result<T, E>>` to `Poll<Result<U, E>>` by applying a
|
|
/// function to a contained `Poll::Ready(Ok)` value, leaving all other
|
|
/// variants untouched.
|
|
///
|
|
/// This function can be used to compose the results of two functions.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// # use core::task::Poll;
|
|
/// let res: Poll<Result<u8, _>> = Poll::Ready("12".parse());
|
|
/// let squared = res.map_ok(|n| n * n);
|
|
/// assert_eq!(squared, Poll::Ready(Ok(144)));
|
|
/// ```
|
|
#[stable(feature = "futures_api", since = "1.36.0")]
|
|
pub fn map_ok<U, F>(self, f: F) -> Poll<Result<U, E>>
|
|
where
|
|
F: FnOnce(T) -> U,
|
|
{
|
|
match self {
|
|
Poll::Ready(Ok(t)) => Poll::Ready(Ok(f(t))),
|
|
Poll::Ready(Err(e)) => Poll::Ready(Err(e)),
|
|
Poll::Pending => Poll::Pending,
|
|
}
|
|
}
|
|
|
|
/// Maps a `Poll::Ready<Result<T, E>>` to `Poll::Ready<Result<T, F>>` by
|
|
/// applying a function to a contained `Poll::Ready(Err)` value, leaving all other
|
|
/// variants untouched.
|
|
///
|
|
/// This function can be used to pass through a successful result while handling
|
|
/// an error.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// # use core::task::Poll;
|
|
/// let res: Poll<Result<u8, _>> = Poll::Ready("oops".parse());
|
|
/// let res = res.map_err(|_| 0_u8);
|
|
/// assert_eq!(res, Poll::Ready(Err(0)));
|
|
/// ```
|
|
#[stable(feature = "futures_api", since = "1.36.0")]
|
|
pub fn map_err<U, F>(self, f: F) -> Poll<Result<T, U>>
|
|
where
|
|
F: FnOnce(E) -> U,
|
|
{
|
|
match self {
|
|
Poll::Ready(Ok(t)) => Poll::Ready(Ok(t)),
|
|
Poll::Ready(Err(e)) => Poll::Ready(Err(f(e))),
|
|
Poll::Pending => Poll::Pending,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<T, E> Poll<Option<Result<T, E>>> {
|
|
/// Maps a `Poll<Option<Result<T, E>>>` to `Poll<Option<Result<U, E>>>` by
|
|
/// applying a function to a contained `Poll::Ready(Some(Ok))` value,
|
|
/// leaving all other variants untouched.
|
|
///
|
|
/// This function can be used to compose the results of two functions.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// # use core::task::Poll;
|
|
/// let res: Poll<Option<Result<u8, _>>> = Poll::Ready(Some("12".parse()));
|
|
/// let squared = res.map_ok(|n| n * n);
|
|
/// assert_eq!(squared, Poll::Ready(Some(Ok(144))));
|
|
/// ```
|
|
#[stable(feature = "poll_map", since = "1.51.0")]
|
|
pub fn map_ok<U, F>(self, f: F) -> Poll<Option<Result<U, E>>>
|
|
where
|
|
F: FnOnce(T) -> U,
|
|
{
|
|
match self {
|
|
Poll::Ready(Some(Ok(t))) => Poll::Ready(Some(Ok(f(t)))),
|
|
Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(e))),
|
|
Poll::Ready(None) => Poll::Ready(None),
|
|
Poll::Pending => Poll::Pending,
|
|
}
|
|
}
|
|
|
|
/// Maps a `Poll::Ready<Option<Result<T, E>>>` to
|
|
/// `Poll::Ready<Option<Result<T, F>>>` by applying a function to a
|
|
/// contained `Poll::Ready(Some(Err))` value, leaving all other variants
|
|
/// untouched.
|
|
///
|
|
/// This function can be used to pass through a successful result while handling
|
|
/// an error.
|
|
///
|
|
/// # Examples
|
|
///
|
|
/// ```
|
|
/// # use core::task::Poll;
|
|
/// let res: Poll<Option<Result<u8, _>>> = Poll::Ready(Some("oops".parse()));
|
|
/// let res = res.map_err(|_| 0_u8);
|
|
/// assert_eq!(res, Poll::Ready(Some(Err(0))));
|
|
/// ```
|
|
#[stable(feature = "poll_map", since = "1.51.0")]
|
|
pub fn map_err<U, F>(self, f: F) -> Poll<Option<Result<T, U>>>
|
|
where
|
|
F: FnOnce(E) -> U,
|
|
{
|
|
match self {
|
|
Poll::Ready(Some(Ok(t))) => Poll::Ready(Some(Ok(t))),
|
|
Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(f(e)))),
|
|
Poll::Ready(None) => Poll::Ready(None),
|
|
Poll::Pending => Poll::Pending,
|
|
}
|
|
}
|
|
}
|
|
|
|
#[stable(feature = "futures_api", since = "1.36.0")]
|
|
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
|
|
impl<T> const From<T> for Poll<T> {
|
|
/// Moves the value into a [`Poll::Ready`] to make a `Poll<T>`.
|
|
///
|
|
/// # Example
|
|
///
|
|
/// ```
|
|
/// # use core::task::Poll;
|
|
/// assert_eq!(Poll::from(true), Poll::Ready(true));
|
|
/// ```
|
|
fn from(t: T) -> Poll<T> {
|
|
Poll::Ready(t)
|
|
}
|
|
}
|
|
|
|
#[unstable(feature = "try_trait_v2", issue = "84277")]
|
|
impl<T, E> ops::Try for Poll<Result<T, E>> {
|
|
type Output = Poll<T>;
|
|
type Residual = Result<convert::Infallible, E>;
|
|
|
|
#[inline]
|
|
fn from_output(c: Self::Output) -> Self {
|
|
c.map(Ok)
|
|
}
|
|
|
|
#[inline]
|
|
fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
|
|
match self {
|
|
Poll::Ready(Ok(x)) => ControlFlow::Continue(Poll::Ready(x)),
|
|
Poll::Ready(Err(e)) => ControlFlow::Break(Err(e)),
|
|
Poll::Pending => ControlFlow::Continue(Poll::Pending),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[unstable(feature = "try_trait_v2", issue = "84277")]
|
|
impl<T, E, F: From<E>> ops::FromResidual<Result<convert::Infallible, E>> for Poll<Result<T, F>> {
|
|
#[inline]
|
|
fn from_residual(x: Result<convert::Infallible, E>) -> Self {
|
|
match x {
|
|
Err(e) => Poll::Ready(Err(From::from(e))),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[unstable(feature = "try_trait_v2", issue = "84277")]
|
|
impl<T, E> ops::Try for Poll<Option<Result<T, E>>> {
|
|
type Output = Poll<Option<T>>;
|
|
type Residual = Result<convert::Infallible, E>;
|
|
|
|
#[inline]
|
|
fn from_output(c: Self::Output) -> Self {
|
|
c.map(|x| x.map(Ok))
|
|
}
|
|
|
|
#[inline]
|
|
fn branch(self) -> ControlFlow<Self::Residual, Self::Output> {
|
|
match self {
|
|
Poll::Ready(Some(Ok(x))) => ControlFlow::Continue(Poll::Ready(Some(x))),
|
|
Poll::Ready(Some(Err(e))) => ControlFlow::Break(Err(e)),
|
|
Poll::Ready(None) => ControlFlow::Continue(Poll::Ready(None)),
|
|
Poll::Pending => ControlFlow::Continue(Poll::Pending),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[unstable(feature = "try_trait_v2", issue = "84277")]
|
|
impl<T, E, F: From<E>> ops::FromResidual<Result<convert::Infallible, E>>
|
|
for Poll<Option<Result<T, F>>>
|
|
{
|
|
#[inline]
|
|
fn from_residual(x: Result<convert::Infallible, E>) -> Self {
|
|
match x {
|
|
Err(e) => Poll::Ready(Some(Err(From::from(e)))),
|
|
}
|
|
}
|
|
}
|