async_iter.rs - source
Description: Source of the Rust file `library/core/src/async_iter/async_iter.rs`.

#
core/async_iter/
async_iter.rs

    1use crate::ops::DerefMut;
    2use crate::pin::Pin;
    3use crate::task::{Context, Poll};
    4
    5/// A trait for dealing with asynchronous iterators.
    6///
    7/// This is the main async iterator trait. For more about the concept of async iterators
    8/// generally, please see the [module-level documentation]. In particular, you
    9/// may want to know how to [implement `AsyncIterator`][impl].
    10///
    11/// [module-level documentation]: index.html
    12/// [impl]: index.html#implementing-async-iterator
    13#[unstable(feature = "async_iterator", issue = "79024")]
    14#[must_use = "async iterators do nothing unless polled"]
    15#[doc(alias = "Stream")]
    16#[lang = "async_iterator"]
    17pub trait AsyncIterator {
    18    /// The type of items yielded by the async iterator.
    19    type Item;
    20
    21    /// Attempts to pull out the next value of this async iterator, registering the
    22    /// current task for wakeup if the value is not yet available, and returning
    23    /// `None` if the async iterator is exhausted.
    24    ///
    25    /// # Return value
    26    ///
    27    /// There are several possible return values, each indicating a distinct
    28    /// async iterator state:
    29    ///
    30    /// - `Poll::Pending` means that this async iterator's next value is not ready
    31    ///   yet. Implementations will ensure that the current task will be notified
    32    ///   when the next value may be ready.
    33    ///
    34    /// - `Poll::Ready(Some(val))` means that the async iterator has successfully
    35    ///   produced a value, `val`, and may produce further values on subsequent
    36    ///   `poll_next` calls.
    37    ///
    38    /// - `Poll::Ready(None)` means that the async iterator has terminated, and
    39    ///   `poll_next` should not be invoked again.
    40    ///
    41    /// # Panics
    42    ///
    43    /// Once an async iterator has finished (returned `Ready(None)` from `poll_next`), calling its
    44    /// `poll_next` method again may panic, block forever, or cause other kinds of
    45    /// problems; the `AsyncIterator` trait places no requirements on the effects of
    46    /// such a call. However, as the `poll_next` method is not marked `unsafe`,
    47    /// Rust's usual rules apply: calls must never cause undefined behavior
    48    /// (memory corruption, incorrect use of `unsafe` functions, or the like),
    49    /// regardless of the async iterator's state.
    50    #[lang = "async_iterator_poll_next"]
    51    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>;
    52
    53    /// Returns the bounds on the remaining length of the async iterator.
    54    ///
    55    /// Specifically, `size_hint()` returns a tuple where the first element
    56    /// is the lower bound, and the second element is the upper bound.
    57    ///
    58    /// The second half of the tuple that is returned is an <code>[Option]<[usize]></code>.
    59    /// A [`None`] here means that either there is no known upper bound, or the
    60    /// upper bound is larger than [`usize`].
    61    ///
    62    /// # Implementation notes
    63    ///
    64    /// It is not enforced that an async iterator implementation yields the declared
    65    /// number of elements. A buggy async iterator may yield less than the lower bound
    66    /// or more than the upper bound of elements.
    67    ///
    68    /// `size_hint()` is primarily intended to be used for optimizations such as
    69    /// reserving space for the elements of the async iterator, but must not be
    70    /// trusted to e.g., omit bounds checks in unsafe code. An incorrect
    71    /// implementation of `size_hint()` should not lead to memory safety
    72    /// violations.
    73    ///
    74    /// That said, the implementation should provide a correct estimation,
    75    /// because otherwise it would be a violation of the trait's protocol.
    76    ///
    77    /// The default implementation returns <code>(0, [None])</code> which is correct for any
    78    /// async iterator.
    79    #[inline]
    80    fn size_hint(&self) -> (usize, Option<usize>) {
    81        (0, None)
    82    }
    83}
    84
    85#[unstable(feature = "async_iterator", issue = "79024")]
    86impl<S: ?Sized + AsyncIterator + Unpin> AsyncIterator for &mut S {
    87    type Item = S::Item;
    88
    89    fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
    90        S::poll_next(Pin::new(&mut **self), cx)
    91    }
    92
    93    fn size_hint(&self) -> (usize, Option<usize>) {
    94        (**self).size_hint()
    95    }
    96}
    97
    98#[unstable(feature = "async_iterator", issue = "79024")]
    99impl<P> AsyncIterator for Pin<P>
    100where
    101    P: DerefMut,
    102    P::Target: AsyncIterator,
    103{
    104    type Item = <P::Target as AsyncIterator>::Item;
    105
    106    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
    107        <P::Target as AsyncIterator>::poll_next(self.as_deref_mut(), cx)
    108    }
    109
    110    fn size_hint(&self) -> (usize, Option<usize>) {
    111        (**self).size_hint()
    112    }
    113}
    114
    115#[unstable(feature = "async_gen_internals", issue = "none")]
    116impl<T> Poll<Option<T>> {
    117    /// A helper function for internal desugaring -- produces `Ready(Some(t))`,
    118    /// which corresponds to the async iterator yielding a value.
    119    #[doc(hidden)]
    120    #[unstable(feature = "async_gen_internals", issue = "none")]
    121    #[lang = "AsyncGenReady"]
    122    pub fn async_gen_ready(t: T) -> Self {
    123        Poll::Ready(Some(t))
    124    }
    125
    126    /// A helper constant for internal desugaring -- produces `Pending`,
    127    /// which corresponds to the async iterator pending on an `.await`.
    128    #[doc(hidden)]
    129    #[unstable(feature = "async_gen_internals", issue = "none")]
    130    #[lang = "AsyncGenPending"]
    131    // FIXME(gen_blocks): This probably could be deduplicated.
    132    pub const PENDING: Self = Poll::Pending;
    133
    134    /// A helper constant for internal desugaring -- produces `Ready(None)`,
    135    /// which corresponds to the async iterator finishing its iteration.
    136    #[doc(hidden)]
    137    #[unstable(feature = "async_gen_internals", issue = "none")]
    138    #[lang = "AsyncGenFinished"]
    139    pub const FINISHED: Self = Poll::Ready(None);
    140}
    141
    142/// Converts something into an async iterator
    143#[unstable(feature = "async_iterator", issue = "79024")]
    144pub trait IntoAsyncIterator {
    145    /// The type of the item yielded by the iterator
    146    type Item;
    147    /// The type of the resulting iterator
    148    type IntoAsyncIter: AsyncIterator<Item = Self::Item>;
    149
    150    /// Converts `self` into an async iterator
    151    #[lang = "into_async_iter_into_iter"]
    152    fn into_async_iter(self) -> Self::IntoAsyncIter;
    153}
    154
    155#[unstable(feature = "async_iterator", issue = "79024")]
    156impl<I: AsyncIterator> IntoAsyncIterator for I {
    157    type Item = I::Item;
    158    type IntoAsyncIter = I;
    159
    160    fn into_async_iter(self) -> Self::IntoAsyncIter {
    161        self
    162    }
    163}