      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

    //! Composable asynchronous iteration.
    //!
    //! If futures are asynchronous values, then streams are asynchronous
    //! iterators. If you've found yourself with an asynchronous collection of some kind,
    //! and needed to perform an operation on the elements of said collection,
    //! you'll quickly run into 'streams'. Streams are heavily used in idiomatic
    //! asynchronous Rust code, so it's worth becoming familiar with them.
    //!
    //! Before explaining more, let's talk about how this module is structured:
    //!
    //! # Organization
    //!
    //! This module is largely organized by type:
    //!
    //! * [Traits] are the core portion: these traits define what kind of streams
    //!   exist and what you can do with them. The methods of these traits are worth
    //!   putting some extra study time into.
    //! * Functions provide some helpful ways to create some basic streams.
    //! * Structs are often the return types of the various methods on this
    //!   module's traits. You'll usually want to look at the method that creates
    //!   the `struct`, rather than the `struct` itself. For more detail about why,
    //!   see '[Implementing Stream](#implementing-stream)'.
    //!
    //! [Traits]: #traits
    //!
    //! That's it! Let's dig into streams.
    //!
    //! # Stream
    //!
    //! The heart and soul of this module is the [`Stream`] trait. The core of
    //! [`Stream`] looks like this:
    //!
    //! ```
    //! # use core::task::{Context, Poll};
    //! # use core::pin::Pin;
    //! trait Stream {
    //!     type Item;
    //!     fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>>;
    //! }
    //! ```
    //!
    //! Unlike `Iterator`, `Stream` makes a distinction between the [`poll_next`]
    //! method which is used when implementing a `Stream`, and a (to-be-implemented)
    //! `next` method which is used when consuming a stream. Consumers of `Stream`
    //! only need to consider `next`, which when called, returns a future which
    //! yields `Option<Stream::Item>`.
    //!
    //! The future returned by `next` will yield `Some(Item)` as long as there are
    //! elements, and once they've all been exhausted, will yield `None` to indicate
    //! that iteration is finished. If we're waiting on something asynchronous to
    //! resolve, the future will wait until the stream is ready to yield again.
    //!
    //! Individual streams may choose to resume iteration, and so calling `next`
    //! again may or may not eventually yield `Some(Item)` again at some point.
    //!
    //! [`Stream`]'s full definition includes a number of other methods as well,
    //! but they are default methods, built on top of [`poll_next`], and so you get
    //! them for free.
    //!
    //! [`Poll`]: super::task::Poll
    //! [`poll_next`]: Stream::poll_next
    //!
    //! # Implementing Stream
    //!
    //! Creating a stream of your own involves two steps: creating a `struct` to
    //! hold the stream's state, and then implementing [`Stream`] for that
    //! `struct`.
    //!
    //! Let's make a stream named `Counter` which counts from `1` to `5`:
    //!
    //! ```no_run
    //! #![feature(async_stream)]
    //! # use core::stream::Stream;
    //! # use core::task::{Context, Poll};
    //! # use core::pin::Pin;
    //!
    //! // First, the struct:
    //!
    //! /// A stream which counts from one to five
    //! struct Counter {
    //!     count: usize,
    //! }
    //!
    //! // we want our count to start at one, so let's add a new() method to help.
    //! // This isn't strictly necessary, but is convenient. Note that we start
    //! // `count` at zero, we'll see why in `poll_next()`'s implementation below.
    //! impl Counter {
    //!     fn new() -> Counter {
    //!         Counter { count: 0 }
    //!     }
    //! }
    //!
    //! // Then, we implement `Stream` for our `Counter`:
    //!
    //! impl Stream for Counter {
    //!     // we will be counting with usize
    //!     type Item = usize;
    //!
    //!     // poll_next() is the only required method
    //!     fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
    //!         // Increment our count. This is why we started at zero.
    //!         self.count += 1;
    //!
    //!         // Check to see if we've finished counting or not.
    //!         if self.count < 6 {
    //!             Poll::Ready(Some(self.count))
    //!         } else {
    //!             Poll::Ready(None)
    //!         }
    //!     }
    //! }
    //! ```
    //!
    //! # Laziness
    //!
    //! Streams are *lazy*. This means that just creating a stream doesn't _do_ a
    //! whole lot. Nothing really happens until you call `next`. This is sometimes a
    //! source of confusion when creating a stream solely for its side effects. The
    //! compiler will warn us about this kind of behavior:
    //!
    //! ```text
    //! warning: unused result that must be used: streams do nothing unless polled
    //! ```

    mod stream;

    pub use stream::Stream;