async_std/stream/
exact_size_stream.rs

1pub use crate::stream::Stream;
2
3/// A stream that knows its exact length.
4///
5/// Many [`Stream`]s don't know how many times they will iterate, but some do.
6/// If a stream knows how many times it can iterate, providing access to
7/// that information can be useful. For example, if you want to iterate
8/// backwards, a good start is to know where the end is.
9///
10/// When implementing an `ExactSizeStream`, you must also implement
11/// [`Stream`]. When doing so, the implementation of [`size_hint`] *must*
12/// return the exact size of the stream.
13///
14/// [`Stream`]: trait.Stream.html
15/// [`size_hint`]: trait.Stream.html#method.size_hint
16///
17/// The [`len`] method has a default implementation, so you usually shouldn't
18/// implement it. However, you may be able to provide a more performant
19/// implementation than the default, so overriding it in this case makes sense.
20///
21/// [`len`]: #method.len
22///
23/// # Examples
24///
25/// Basic usage:
26///
27/// ```
28/// // a finite range knows exactly how many times it will iterate
29/// let five = 0..5;
30///
31/// assert_eq!(5, five.len());
32/// ```
33///
34/// In the [module level docs][moddocs], we implemented an [`Stream`],
35/// `Counter`. Let's implement `ExactSizeStream` for it as well:
36///
37/// [moddocs]: index.html
38///
39/// ```
40/// # use std::task::{Context, Poll};
41/// # use std::pin::Pin;
42/// # use async_std::prelude::*;
43/// # struct Counter {
44/// #     count: usize,
45/// # }
46/// # impl Counter {
47/// #     fn new() -> Counter {
48/// #         Counter { count: 0 }
49/// #     }
50/// # }
51/// # impl Stream for Counter {
52/// #     type Item = usize;
53/// #     fn poll_next(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
54/// #         self.count += 1;
55/// #         if self.count < 6 {
56/// #             Poll::Ready(Some(self.count))
57/// #         } else {
58/// #             Poll::Ready(None)
59/// #         }
60/// #     }
61/// # }
62/// # async_std::task::block_on(async {
63/// #
64/// impl ExactSizeStream for Counter {
65///     // We can easily calculate the remaining number of iterations.
66///     fn len(&self) -> usize {
67///         5 - self.count
68///     }
69/// }
70///
71/// // And now we can use it!
72///
73/// let counter = Counter::new();
74///
75/// assert_eq!(5, counter.len());
76/// # });
77/// ```
78#[allow(clippy::len_without_is_empty)] // ExactSizeIterator::is_empty is unstable
79#[cfg(feature = "unstable")]
80#[cfg_attr(feature = "docs", doc(cfg(unstable)))]
81pub trait ExactSizeStream: Stream {
82    /// Returns the exact number of times the stream will iterate.
83    ///
84    /// This method has a default implementation, so you usually should not
85    /// implement it directly. However, if you can provide a more efficient
86    /// implementation, you can do so. See the [trait-level] docs for an
87    /// example.
88    ///
89    /// This function has the same safety guarantees as the [`size_hint`]
90    /// function.
91    ///
92    /// [trait-level]: trait.ExactSizeStream.html
93    /// [`size_hint`]: trait.Stream.html#method.size_hint
94    ///
95    /// # Examples
96    ///
97    /// Basic usage:
98    ///
99    /// ```
100    /// // a finite range knows exactly how many times it will iterate
101    /// let five = 0..5;
102    ///
103    /// assert_eq!(5, five.len());
104    /// ```
105    fn len(&self) -> usize {
106        let (lower, upper) = self.size_hint();
107        // Note: This assertion is overly defensive, but it checks the invariant
108        // guaranteed by the trait. If this trait were rust-internal,
109        // we could use debug_assert!; assert_eq! will check all Rust user
110        // implementations too.
111        assert_eq!(upper, Some(lower));
112        lower
113    }
114}
115
116impl<I: ExactSizeStream + ?Sized + Unpin> ExactSizeStream for &mut I {
117    fn len(&self) -> usize {
118        (**self).len()
119    }
120}