mirror of
				https://github.com/async-rs/async-std.git
				synced 2025-10-25 05:46:43 +00:00 
			
		
		
		
	add stream::ExactSizeStream as unstable (#330)
Signed-off-by: Yoshua Wuyts <yoshuawuyts@gmail.com>
This commit is contained in:
		
							parent
							
								
									6be8467cdc
								
							
						
					
					
						commit
						1819408b46
					
				
					 3 changed files with 134 additions and 0 deletions
				
			
		|  | @ -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; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										120
									
								
								src/stream/exact_size_stream.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								src/stream/exact_size_stream.rs
									
									
									
									
									
										Normal file
									
								
							|  | @ -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…
	
		Reference in a new issue