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
pub use crate::stream::Stream;

/// A stream that knows its exact length.

///

/// Many [`Stream`]s don't know how many times they will iterate, but some do.

/// If a stream knows how many times it can iterate, providing access to

/// that information can be useful. For example, if you want to iterate

/// backwards, a good start is to know where the end is.

///

/// When implementing an `ExactSizeStream`, you must also implement

/// [`Stream`]. When doing so, the implementation of [`size_hint`] *must*

/// return the exact size of the stream.

///

/// [`Stream`]: trait.Stream.html

/// [`size_hint`]: trait.Stream.html#method.size_hint

///

/// The [`len`] method has a default implementation, so you usually shouldn't

/// implement it. However, you may be able to provide a more performant

/// implementation than the default, so overriding it in this case makes sense.

///

/// [`len`]: #method.len

///

/// # Examples

///

/// Basic usage:

///

/// ```

/// // a finite range knows exactly how many times it will iterate

/// let five = 0..5;

///

/// assert_eq!(5, five.len());

/// ```

///

/// In the [module level docs][moddocs], we implemented an [`Stream`],

/// `Counter`. Let's implement `ExactSizeStream` for it as well:

///

/// [moddocs]: index.html

///

/// ```

/// # use std::task::{Context, Poll};

/// # use std::pin::Pin;

/// # use async_std::prelude::*;

/// # struct Counter {

/// #     count: usize,

/// # }

/// # impl Counter {

/// #     fn new() -> Counter {

/// #         Counter { count: 0 }

/// #     }

/// # }

/// # impl Stream for Counter {

/// #     type Item = usize;

/// #     fn poll_next(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {

/// #         self.count += 1;

/// #         if self.count < 6 {

/// #             Poll::Ready(Some(self.count))

/// #         } else {

/// #             Poll::Ready(None)

/// #         }

/// #     }

/// # }

/// # async_std::task::block_on(async {

/// #

/// impl ExactSizeStream for Counter {

///     // We can easily calculate the remaining number of iterations.

///     fn len(&self) -> usize {

///         5 - self.count

///     }

/// }

///

/// // And now we can use it!

///

/// let counter = Counter::new();

///

/// assert_eq!(5, counter.len());

/// # });

/// ```

#[allow(clippy::len_without_is_empty)] // ExactSizeIterator::is_empty is unstable

#[cfg(feature = "unstable")]
#[cfg_attr(feature = "docs", doc(cfg(unstable)))]
pub trait ExactSizeStream: Stream {
    /// Returns the exact number of times the stream will iterate.

    ///

    /// This method has a default implementation, so you usually should not

    /// implement it directly. However, if you can provide a more efficient

    /// implementation, you can do so. See the [trait-level] docs for an

    /// example.

    ///

    /// This function has the same safety guarantees as the [`size_hint`]

    /// function.

    ///

    /// [trait-level]: trait.ExactSizeStream.html

    /// [`size_hint`]: trait.Stream.html#method.size_hint

    ///

    /// # Examples

    ///

    /// Basic usage:

    ///

    /// ```

    /// // a finite range knows exactly how many times it will iterate

    /// let five = 0..5;

    ///

    /// assert_eq!(5, five.len());

    /// ```

    fn len(&self) -> usize {
        let (lower, upper) = self.size_hint();
        // Note: This assertion is overly defensive, but it checks the invariant

        // guaranteed by the trait. If this trait were rust-internal,

        // we could use debug_assert!; assert_eq! will check all Rust user

        // implementations too.

        assert_eq!(upper, Some(lower));
        lower
    }
}

impl<I: ExactSizeStream + ?Sized + Unpin> ExactSizeStream for &mut I {
    fn len(&self) -> usize {
        (**self).len()
    }
}