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}