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}