add stream::ExactSizeStream as unstable (#330)

Signed-off-by: Yoshua Wuyts <yoshuawuyts@gmail.com>
yoshuawuyts-patch-1
Yoshua Wuyts 5 years ago committed by Stjepan Glavina
parent 6be8467cdc
commit 1819408b46

@ -11,6 +11,8 @@
//! use async_std::prelude::*; //! use async_std::prelude::*;
//! ``` //! ```
use cfg_if::cfg_if;
#[doc(no_inline)] #[doc(no_inline)]
pub use crate::future::Future; pub use crate::future::Future;
#[doc(no_inline)] #[doc(no_inline)]
@ -36,3 +38,13 @@ pub use crate::io::seek::SeekExt as _;
pub use crate::io::write::WriteExt as _; pub use crate::io::write::WriteExt as _;
#[doc(hidden)] #[doc(hidden)]
pub use crate::stream::stream::StreamExt as _; pub use crate::stream::stream::StreamExt as _;
cfg_if! {
if #[cfg(any(feature = "unstable", feature = "docs"))] {
#[doc(no_inline)]
pub use crate::stream::DoubleEndedStream;
#[doc(no_inline)]
pub use crate::stream::ExactSizeStream;
}
}

@ -0,0 +1,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)
/// # }
/// # }
/// # }
/// # fn main() { 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());
/// # });
/// # }
/// ```
#[cfg_attr(feature = "docs", doc(cfg(unstable)))]
#[cfg(any(feature = "unstable", feature = "docs"))]
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()
}
}

@ -39,12 +39,14 @@ mod repeat;
cfg_if! { cfg_if! {
if #[cfg(any(feature = "unstable", feature = "docs"))] { if #[cfg(any(feature = "unstable", feature = "docs"))] {
mod double_ended_stream; mod double_ended_stream;
mod exact_size_stream;
mod fused_stream; mod fused_stream;
mod extend; mod extend;
mod from_stream; mod from_stream;
mod into_stream; mod into_stream;
pub use double_ended_stream::DoubleEndedStream; pub use double_ended_stream::DoubleEndedStream;
pub use exact_size_stream::ExactSizeStream;
pub use extend::Extend; pub use extend::Extend;
pub use from_stream::FromStream; pub use from_stream::FromStream;
pub use into_stream::IntoStream; pub use into_stream::IntoStream;

Loading…
Cancel
Save