From e19ab626a1a7cef88c11f18a750624bce050f47f Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 11 Mar 2022 09:31:01 +1100 Subject: [PATCH 01/11] Remove unused parameter from `extension_trait!` rules. Two of the rules have `(+ $lt:lifetime)?` that is not used on the RHS and serves no useful purpose. This commit removes it. --- src/io/buf_read/mod.rs | 4 ++-- src/io/read/mod.rs | 10 +++++----- src/io/seek/mod.rs | 2 +- src/io/write/mod.rs | 10 +++++----- src/stream/stream/mod.rs | 24 ++++++++++++------------ src/utils.rs | 4 ++-- 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/io/buf_read/mod.rs b/src/io/buf_read/mod.rs index 7a0ecc60..3ee6e30b 100644 --- a/src/io/buf_read/mod.rs +++ b/src/io/buf_read/mod.rs @@ -124,7 +124,7 @@ extension_trait! { &'a mut self, byte: u8, buf: &'a mut Vec, - ) -> impl Future + 'a [ReadUntilFuture<'a, Self>] + ) -> impl Future [ReadUntilFuture<'a, Self>] where Self: Unpin, { @@ -177,7 +177,7 @@ extension_trait! { fn read_line<'a>( &'a mut self, buf: &'a mut String, - ) -> impl Future> + 'a [ReadLineFuture<'a, Self>] + ) -> impl Future> [ReadLineFuture<'a, Self>] where Self: Unpin, { diff --git a/src/io/read/mod.rs b/src/io/read/mod.rs index 388237c8..c8f4e28b 100644 --- a/src/io/read/mod.rs +++ b/src/io/read/mod.rs @@ -112,7 +112,7 @@ extension_trait! { fn read<'a>( &'a mut self, buf: &'a mut [u8], - ) -> impl Future> + 'a [ReadFuture<'a, Self>] + ) -> impl Future> [ReadFuture<'a, Self>] where Self: Unpin { @@ -134,7 +134,7 @@ extension_trait! { fn read_vectored<'a>( &'a mut self, bufs: &'a mut [IoSliceMut<'a>], - ) -> impl Future> + 'a [ReadVectoredFuture<'a, Self>] + ) -> impl Future> [ReadVectoredFuture<'a, Self>] where Self: Unpin, { @@ -171,7 +171,7 @@ extension_trait! { fn read_to_end<'a>( &'a mut self, buf: &'a mut Vec, - ) -> impl Future> + 'a [ReadToEndFuture<'a, Self>] + ) -> impl Future> [ReadToEndFuture<'a, Self>] where Self: Unpin, { @@ -210,7 +210,7 @@ extension_trait! { fn read_to_string<'a>( &'a mut self, buf: &'a mut String, - ) -> impl Future> + 'a [ReadToStringFuture<'a, Self>] + ) -> impl Future> [ReadToStringFuture<'a, Self>] where Self: Unpin, { @@ -265,7 +265,7 @@ extension_trait! { fn read_exact<'a>( &'a mut self, buf: &'a mut [u8], - ) -> impl Future> + 'a [ReadExactFuture<'a, Self>] + ) -> impl Future> [ReadExactFuture<'a, Self>] where Self: Unpin, { diff --git a/src/io/seek/mod.rs b/src/io/seek/mod.rs index f565ca46..3b5036c8 100644 --- a/src/io/seek/mod.rs +++ b/src/io/seek/mod.rs @@ -76,7 +76,7 @@ extension_trait! { fn seek( &mut self, pos: SeekFrom, - ) -> impl Future> + '_ [SeekFuture<'_, Self>] + ) -> impl Future> [SeekFuture<'_, Self>] where Self: Unpin, { diff --git a/src/io/write/mod.rs b/src/io/write/mod.rs index 0ed91dda..3dee9feb 100644 --- a/src/io/write/mod.rs +++ b/src/io/write/mod.rs @@ -110,7 +110,7 @@ extension_trait! { fn write<'a>( &'a mut self, buf: &'a [u8], - ) -> impl Future> + 'a [WriteFuture<'a, Self>] + ) -> impl Future> [WriteFuture<'a, Self>] where Self: Unpin, { @@ -136,7 +136,7 @@ extension_trait! { # Ok(()) }) } ``` "#] - fn flush(&mut self) -> impl Future> + '_ [FlushFuture<'_, Self>] + fn flush(&mut self) -> impl Future> [FlushFuture<'_, Self>] where Self: Unpin, { @@ -158,7 +158,7 @@ extension_trait! { fn write_vectored<'a>( &'a mut self, bufs: &'a [IoSlice<'a>], - ) -> impl Future> + 'a [WriteVectoredFuture<'a, Self>] + ) -> impl Future> [WriteVectoredFuture<'a, Self>] where Self: Unpin, { @@ -194,7 +194,7 @@ extension_trait! { fn write_all<'a>( &'a mut self, buf: &'a [u8], - ) -> impl Future> + 'a [WriteAllFuture<'a, Self>] + ) -> impl Future> [WriteAllFuture<'a, Self>] where Self: Unpin, { @@ -231,7 +231,7 @@ extension_trait! { fn write_fmt<'a>( &'a mut self, fmt: std::fmt::Arguments<'_>, - ) -> impl Future> + 'a [WriteFmtFuture<'a, Self>] + ) -> impl Future> [WriteFmtFuture<'a, Self>] where Self: Unpin, { diff --git a/src/stream/stream/mod.rs b/src/stream/stream/mod.rs index 4e074a2f..af7407a2 100644 --- a/src/stream/stream/mod.rs +++ b/src/stream/stream/mod.rs @@ -260,7 +260,7 @@ extension_trait! { # }) } ``` "#] - fn next(&mut self) -> impl Future> + '_ [NextFuture<'_, Self>] + fn next(&mut self) -> impl Future> [NextFuture<'_, Self>] where Self: Unpin, { @@ -1165,7 +1165,7 @@ extension_trait! { fn nth( &mut self, n: usize, - ) -> impl Future> + '_ [NthFuture<'_, Self>] + ) -> impl Future> [NthFuture<'_, Self>] where Self: Unpin + Sized, { @@ -1221,7 +1221,7 @@ extension_trait! { fn all( &mut self, f: F, - ) -> impl Future + '_ [AllFuture<'_, Self, F, Self::Item>] + ) -> impl Future [AllFuture<'_, Self, F, Self::Item>] where Self: Unpin + Sized, F: FnMut(Self::Item) -> bool, @@ -1270,7 +1270,7 @@ extension_trait! { fn find

( &mut self, p: P, - ) -> impl Future> + '_ [FindFuture<'_, Self, P>] + ) -> impl Future> [FindFuture<'_, Self, P>] where Self: Unpin + Sized, P: FnMut(&Self::Item) -> bool, @@ -1298,7 +1298,7 @@ extension_trait! { fn find_map( &mut self, f: F, - ) -> impl Future> + '_ [FindMapFuture<'_, Self, F>] + ) -> impl Future> [FindMapFuture<'_, Self, F>] where Self: Unpin + Sized, F: FnMut(Self::Item) -> Option, @@ -1461,7 +1461,7 @@ extension_trait! { fn any( &mut self, f: F, - ) -> impl Future + '_ [AnyFuture<'_, Self, F, Self::Item>] + ) -> impl Future [AnyFuture<'_, Self, F, Self::Item>] where Self: Unpin + Sized, F: FnMut(Self::Item) -> bool, @@ -1697,7 +1697,7 @@ extension_trait! { &mut self, init: T, f: F, - ) -> impl Future> + '_ [TryFoldFuture<'_, Self, F, T>] + ) -> impl Future> [TryFoldFuture<'_, Self, F, T>] where Self: Unpin + Sized, F: FnMut(B, Self::Item) -> Result, @@ -1742,7 +1742,7 @@ extension_trait! { fn try_for_each( &mut self, f: F, - ) -> impl Future + 'a [TryForEachFuture<'_, Self, F>] + ) -> impl Future [TryForEachFuture<'_, Self, F>] where Self: Unpin + Sized, F: FnMut(Self::Item) -> Result<(), E>, @@ -1888,7 +1888,7 @@ extension_trait! { #[cfg_attr(feature = "docs", doc(cfg(unstable)))] fn collect<'a, B>( self, - ) -> impl Future + 'a [Pin + 'a + Send>>] + ) -> impl Future [Pin + 'a + Send>>] where Self: Sized + 'a + Send, B: FromStream, @@ -2002,7 +2002,7 @@ extension_trait! { fn position

( &mut self, predicate: P, - ) -> impl Future> + '_ [PositionFuture<'_, Self, P>] + ) -> impl Future> [PositionFuture<'_, Self, P>] where Self: Unpin + Sized, P: FnMut(Self::Item) -> bool, @@ -2335,7 +2335,7 @@ extension_trait! { #[cfg_attr(feature = "docs", doc(cfg(unstable)))] fn sum<'a, S>( self, - ) -> impl Future + 'a [Pin + 'a>>] + ) -> impl Future [Pin + 'a>>] where Self: Sized + Stream + 'a, S: Sum, @@ -2381,7 +2381,7 @@ extension_trait! { #[cfg_attr(feature = "docs", doc(cfg(unstable)))] fn product<'a, P>( self, - ) -> impl Future + 'a [Pin + 'a>>] + ) -> impl Future [Pin + 'a>>] where Self: Sized + Stream + 'a, P: Product, diff --git a/src/utils.rs b/src/utils.rs index 6ae49115..88731d28 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -302,10 +302,10 @@ macro_rules! extension_trait { }; // Parse the return type in an extension method. - (@doc [-> impl Future $(+ $lt:lifetime)? [$f:ty] $($tail:tt)*] -> [$($accum:tt)*]) => { + (@doc [-> impl Future [$f:ty] $($tail:tt)*] -> [$($accum:tt)*]) => { extension_trait!(@doc [$($tail)*] -> [$($accum)* -> owned::ImplFuture<$out>]); }; - (@ext [-> impl Future $(+ $lt:lifetime)? [$f:ty] $($tail:tt)*] -> [$($accum:tt)*]) => { + (@ext [-> impl Future [$f:ty] $($tail:tt)*] -> [$($accum:tt)*]) => { extension_trait!(@ext [$($tail)*] -> [$($accum)* -> $f]); }; From f56a8d6935112c70a98d023630d54d1f120d6c9c Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 11 Mar 2022 10:09:01 +1100 Subject: [PATCH 02/11] Remove unused `borrowed` module. --- src/utils.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/utils.rs b/src/utils.rs index 88731d28..77111143 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -270,13 +270,6 @@ macro_rules! extension_trait { pub struct ImplFuture(core::marker::PhantomData); } - // A fake `impl Future` type that borrows its environment. - #[allow(dead_code)] - mod borrowed { - #[doc(hidden)] - pub struct ImplFuture<'a, T>(core::marker::PhantomData<&'a T>); - } - // Render a fake trait combining the bodies of the base trait and the extension trait. #[cfg(feature = "docs")] #[doc = $doc] From ed2fcce5578b931a1db0df331661dae86c6c4c6d Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 11 Mar 2022 11:33:18 +1100 Subject: [PATCH 03/11] Remove `docs`-only features from `extension_trait`. This is the `@doc` rules, the shim trait impls, and the imports. --- src/future/future/mod.rs | 41 -------------------- src/io/buf_read/mod.rs | 58 ---------------------------- src/io/read/mod.rs | 50 ------------------------- src/io/seek/mod.rs | 40 -------------------- src/io/write/mod.rs | 81 ---------------------------------------- src/stream/stream/mod.rs | 40 -------------------- src/utils.rs | 38 +------------------ 7 files changed, 1 insertion(+), 347 deletions(-) diff --git a/src/future/future/mod.rs b/src/future/future/mod.rs index 35651450..19432555 100644 --- a/src/future/future/mod.rs +++ b/src/future/future/mod.rs @@ -21,11 +21,6 @@ cfg_unstable_default! { } extension_trait! { - use core::pin::Pin; - use core::ops::{Deref, DerefMut}; - - use crate::task::{Context, Poll}; - #[doc = r#" A future represents an asynchronous computation. @@ -393,40 +388,4 @@ extension_trait! { TimeoutFuture::new(self, dur) } } - - impl Future for Box { - type Output = F::Output; - - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - unreachable!("this impl only appears in the rendered docs") - } - } - - impl Future for &mut F { - type Output = F::Output; - - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - unreachable!("this impl only appears in the rendered docs") - } - } - - impl

Future for Pin

- where - P: DerefMut + Unpin, -

::Target: Future, - { - type Output = <

::Target as Future>::Output; - - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - unreachable!("this impl only appears in the rendered docs") - } - } - - impl Future for std::panic::AssertUnwindSafe { - type Output = F::Output; - - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - unreachable!("this impl only appears in the rendered docs") - } - } } diff --git a/src/io/buf_read/mod.rs b/src/io/buf_read/mod.rs index 3ee6e30b..90bf339d 100644 --- a/src/io/buf_read/mod.rs +++ b/src/io/buf_read/mod.rs @@ -16,8 +16,6 @@ use crate::io; use crate::task::{Context, Poll}; extension_trait! { - use std::ops::{Deref, DerefMut}; - #[doc = r#" Allows reading from a buffered byte stream. @@ -283,62 +281,6 @@ extension_trait! { } } } - - impl BufRead for Box { - fn poll_fill_buf( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll> { - unreachable!("this impl only appears in the rendered docs") - } - - fn consume(self: Pin<&mut Self>, amt: usize) { - unreachable!("this impl only appears in the rendered docs") - } - } - - impl BufRead for &mut T { - fn poll_fill_buf( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll> { - unreachable!("this impl only appears in the rendered docs") - } - - fn consume(self: Pin<&mut Self>, amt: usize) { - unreachable!("this impl only appears in the rendered docs") - } - } - - impl

BufRead for Pin

- where - P: DerefMut + Unpin, -

::Target: BufRead, - { - fn poll_fill_buf( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll> { - unreachable!("this impl only appears in the rendered docs") - } - - fn consume(self: Pin<&mut Self>, amt: usize) { - unreachable!("this impl only appears in the rendered docs") - } - } - - impl BufRead for &[u8] { - fn poll_fill_buf( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll> { - unreachable!() - } - - fn consume(self: Pin<&mut Self>, amt: usize) { - unreachable!("this impl only appears in the rendered docs") - } - } } pub fn read_until_internal( diff --git a/src/io/read/mod.rs b/src/io/read/mod.rs index c8f4e28b..8c6d3a3e 100644 --- a/src/io/read/mod.rs +++ b/src/io/read/mod.rs @@ -22,12 +22,6 @@ pub use chain::Chain; pub use take::Take; extension_trait! { - use std::pin::Pin; - use std::ops::{Deref, DerefMut}; - - use crate::io; - use crate::task::{Context, Poll}; - #[doc = r#" Allows reading from a byte stream. @@ -422,50 +416,6 @@ extension_trait! { } } - - impl Read for Box { - fn poll_read( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - buf: &mut [u8], - ) -> Poll> { - unreachable!("this impl only appears in the rendered docs") - } - } - - impl Read for &mut T { - fn poll_read( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - buf: &mut [u8], - ) -> Poll> { - unreachable!("this impl only appears in the rendered docs") - } - } - - impl

Read for Pin

- where - P: DerefMut + Unpin, -

::Target: Read, - { - fn poll_read( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - buf: &mut [u8], - ) -> Poll> { - unreachable!("this impl only appears in the rendered docs") - } - } - - impl Read for &[u8] { - fn poll_read( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - buf: &mut [u8], - ) -> Poll> { - unreachable!("this impl only appears in the rendered docs") - } - } } /// Initializes a buffer if necessary. diff --git a/src/io/seek/mod.rs b/src/io/seek/mod.rs index 3b5036c8..748a1ed9 100644 --- a/src/io/seek/mod.rs +++ b/src/io/seek/mod.rs @@ -5,12 +5,6 @@ use seek::SeekFuture; use crate::io::SeekFrom; extension_trait! { - use std::ops::{Deref, DerefMut}; - use std::pin::Pin; - - use crate::io; - use crate::task::{Context, Poll}; - #[doc = r#" Allows seeking through a byte stream. @@ -83,38 +77,4 @@ extension_trait! { SeekFuture { seeker: self, pos } } } - - impl Seek for Box { - fn poll_seek( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - pos: SeekFrom, - ) -> Poll> { - unreachable!("this impl only appears in the rendered docs") - } - } - - impl Seek for &mut T { - fn poll_seek( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - pos: SeekFrom, - ) -> Poll> { - unreachable!("this impl only appears in the rendered docs") - } - } - - impl

Seek for Pin

- where - P: DerefMut + Unpin, -

::Target: Seek, - { - fn poll_seek( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - pos: SeekFrom, - ) -> Poll> { - unreachable!("this impl only appears in the rendered docs") - } - } } diff --git a/src/io/write/mod.rs b/src/io/write/mod.rs index 3dee9feb..b0ed8eec 100644 --- a/src/io/write/mod.rs +++ b/src/io/write/mod.rs @@ -13,11 +13,6 @@ use write_vectored::WriteVectoredFuture; use crate::io::{self, IoSlice}; extension_trait! { - use std::pin::Pin; - use std::ops::{Deref, DerefMut}; - - use crate::task::{Context, Poll}; - #[doc = r#" Allows writing to a byte stream. @@ -245,80 +240,4 @@ extension_trait! { WriteFmtFuture { writer: self, res: Some(res), buffer: None, amt: 0 } } } - - impl Write for Box { - fn poll_write( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - buf: &[u8], - ) -> Poll> { - unreachable!("this impl only appears in the rendered docs") - } - - fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - unreachable!("this impl only appears in the rendered docs") - } - - fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - unreachable!("this impl only appears in the rendered docs") - } - } - - impl Write for &mut T { - fn poll_write( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - buf: &[u8], - ) -> Poll> { - unreachable!("this impl only appears in the rendered docs") - } - - fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - unreachable!("this impl only appears in the rendered docs") - } - - fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - unreachable!("this impl only appears in the rendered docs") - } - } - - impl

Write for Pin

- where - P: DerefMut + Unpin, -

::Target: Write, - { - fn poll_write( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - buf: &[u8], - ) -> Poll> { - unreachable!("this impl only appears in the rendered docs") - } - - fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - unreachable!("this impl only appears in the rendered docs") - } - - fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - unreachable!("this impl only appears in the rendered docs") - } - } - - impl Write for Vec { - fn poll_write( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - buf: &[u8], - ) -> Poll> { - unreachable!("this impl only appears in the rendered docs") - } - - fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - unreachable!("this impl only appears in the rendered docs") - } - - fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - unreachable!("this impl only appears in the rendered docs") - } - } } diff --git a/src/stream/stream/mod.rs b/src/stream/stream/mod.rs index af7407a2..90c5cb7a 100644 --- a/src/stream/stream/mod.rs +++ b/src/stream/stream/mod.rs @@ -144,10 +144,6 @@ cfg_unstable! { } extension_trait! { - use std::ops::{Deref, DerefMut}; - - use crate::task::{Context, Poll}; - #[doc = r#" An asynchronous stream of values. @@ -2389,40 +2385,4 @@ extension_trait! { Product::product(self) } } - - impl Stream for Box { - type Item = S::Item; - - fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - unreachable!("this impl only appears in the rendered docs") - } - } - - impl Stream for &mut S { - type Item = S::Item; - - fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - unreachable!("this impl only appears in the rendered docs") - } - } - - impl

Stream for Pin

- where - P: DerefMut + Unpin, -

::Target: Stream, - { - type Item = <

::Target as Stream>::Item; - - fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - unreachable!("this impl only appears in the rendered docs") - } - } - - impl Stream for std::panic::AssertUnwindSafe { - type Item = S::Item; - - fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - unreachable!("this impl only appears in the rendered docs") - } - } } diff --git a/src/utils.rs b/src/utils.rs index 77111143..8b8ee23f 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -259,26 +259,8 @@ macro_rules! extension_trait { pub trait $ext:ident: $base:path { $($body_ext:tt)* } - - // Shim trait impls that only appear in docs. - $($imp:item)* ) => { - // A fake `impl Future` type that doesn't borrow. - #[allow(dead_code)] - mod owned { - #[doc(hidden)] - pub struct ImplFuture(core::marker::PhantomData); - } - - // Render a fake trait combining the bodies of the base trait and the extension trait. - #[cfg(feature = "docs")] - #[doc = $doc] - pub trait $name { - extension_trait!(@doc [$($body_base)* $($body_ext)*] -> []); - } - - // When not rendering docs, re-export the base trait from the futures crate. - #[cfg(not(feature = "docs"))] + // Re-export the base trait from the futures crate. pub use $base as $name; // The extension trait that adds methods to any type implementing the base trait. @@ -289,36 +271,18 @@ macro_rules! extension_trait { // Blanket implementation of the extension trait for any type implementing the base trait. impl $ext for T {} - - // Shim trait impls that only appear in docs. - $(#[cfg(feature = "docs")] $imp)* }; // Parse the return type in an extension method. - (@doc [-> impl Future [$f:ty] $($tail:tt)*] -> [$($accum:tt)*]) => { - extension_trait!(@doc [$($tail)*] -> [$($accum)* -> owned::ImplFuture<$out>]); - }; (@ext [-> impl Future [$f:ty] $($tail:tt)*] -> [$($accum:tt)*]) => { extension_trait!(@ext [$($tail)*] -> [$($accum)* -> $f]); }; // Parse a token. - (@doc [$token:tt $($tail:tt)*] -> [$($accum:tt)*]) => { - extension_trait!(@doc [$($tail)*] -> [$($accum)* $token]); - }; (@ext [$token:tt $($tail:tt)*] -> [$($accum:tt)*]) => { extension_trait!(@ext [$($tail)*] -> [$($accum)* $token]); }; // Handle the end of the token list. - (@doc [] -> [$($accum:tt)*]) => { $($accum)* }; (@ext [] -> [$($accum:tt)*]) => { $($accum)* }; - - // Parse imports at the beginning of the macro. - ($import:item $($tail:tt)*) => { - #[cfg(feature = "docs")] - $import - - extension_trait!($($tail)*); - }; } From c10d2d3a6f2e87e4a82bdcd73cda8cd6ca173945 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 11 Mar 2022 11:52:44 +1100 Subject: [PATCH 04/11] Simplify the first trait in `extension_trait`. The body and doc comment are no longer used. --- src/future/future/mod.rs | 105 +-------------------------------------- src/io/buf_read/mod.rs | 46 +---------------- src/io/read/mod.rs | 44 +--------------- src/io/seek/mod.rs | 32 +----------- src/io/write/mod.rs | 58 +-------------------- src/stream/stream/mod.rs | 81 +----------------------------- src/utils.rs | 5 +- 7 files changed, 7 insertions(+), 364 deletions(-) diff --git a/src/future/future/mod.rs b/src/future/future/mod.rs index 19432555..a913f4fc 100644 --- a/src/future/future/mod.rs +++ b/src/future/future/mod.rs @@ -21,110 +21,7 @@ cfg_unstable_default! { } extension_trait! { - #[doc = r#" - A future represents an asynchronous computation. - - A future is a value that may not have finished computing yet. This kind of - "asynchronous value" makes it possible for a thread to continue doing useful - work while it waits for the value to become available. - - The [provided methods] do not really exist in the trait itself, but they become - available when [`FutureExt`] from the [prelude] is imported: - - ``` - # #[allow(unused_imports)] - use async_std::prelude::*; - ``` - - # The `poll` method - - The core method of future, `poll`, *attempts* to resolve the future into a - final value. This method does not block if the value is not ready. Instead, - the current task is scheduled to be woken up when it's possible to make - further progress by `poll`ing again. The `context` passed to the `poll` - method can provide a [`Waker`], which is a handle for waking up the current - task. - - When using a future, you generally won't call `poll` directly, but instead - `.await` the value. - - [`Waker`]: ../task/struct.Waker.html - [provided methods]: #provided-methods - [`FutureExt`]: ../prelude/trait.FutureExt.html - [prelude]: ../prelude/index.html - "#] - pub trait Future { - #[doc = r#" - The type of value produced on completion. - "#] - type Output; - - #[doc = r#" - Attempt to resolve the future to a final value, registering - the current task for wakeup if the value is not yet available. - - # Return value - - This function returns: - - - [`Poll::Pending`] if the future is not ready yet - - [`Poll::Ready(val)`] with the result `val` of this future if it - finished successfully. - - Once a future has finished, clients should not `poll` it again. - - When a future is not ready yet, `poll` returns `Poll::Pending` and - stores a clone of the [`Waker`] copied from the current [`Context`]. - This [`Waker`] is then woken once the future can make progress. - For example, a future waiting for a socket to become - readable would call `.clone()` on the [`Waker`] and store it. - When a signal arrives elsewhere indicating that the socket is readable, - [`Waker::wake`] is called and the socket future's task is awoken. - Once a task has been woken up, it should attempt to `poll` the future - again, which may or may not produce a final value. - - Note that on multiple calls to `poll`, only the [`Waker`] from the - [`Context`] passed to the most recent call should be scheduled to - receive a wakeup. - - # Runtime characteristics - - Futures alone are *inert*; they must be *actively* `poll`ed to make - progress, meaning that each time the current task is woken up, it should - actively re-`poll` pending futures that it still has an interest in. - - The `poll` function is not called repeatedly in a tight loop -- instead, - it should only be called when the future indicates that it is ready to - make progress (by calling `wake()`). If you're familiar with the - `poll(2)` or `select(2)` syscalls on Unix it's worth noting that futures - typically do *not* suffer the same problems of "all wakeups must poll - all events"; they are more like `epoll(4)`. - - An implementation of `poll` should strive to return quickly, and should - not block. Returning quickly prevents unnecessarily clogging up - threads or event loops. If it is known ahead of time that a call to - `poll` may end up taking awhile, the work should be offloaded to a - thread pool (or something similar) to ensure that `poll` can return - quickly. - - # Panics - - Once a future has completed (returned `Ready` from `poll`), calling its - `poll` method again may panic, block forever, or cause other kinds of - problems; the `Future` trait places no requirements on the effects of - such a call. However, as the `poll` method is not marked `unsafe`, - Rust's usual rules apply: calls must never cause undefined behavior - (memory corruption, incorrect use of `unsafe` functions, or the like), - regardless of the future's state. - - [`Poll::Pending`]: ../task/enum.Poll.html#variant.Pending - [`Poll::Ready(val)`]: ../task/enum.Poll.html#variant.Ready - [`Context`]: ../task/struct.Context.html - [`Waker`]: ../task/struct.Waker.html - [`Waker::wake`]: ../task/struct.Waker.html#method.wake - "#] - fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll; - } + pub trait Future {} #[doc = r#" Extension methods for [`Future`]. diff --git a/src/io/buf_read/mod.rs b/src/io/buf_read/mod.rs index 90bf339d..d42cbd8a 100644 --- a/src/io/buf_read/mod.rs +++ b/src/io/buf_read/mod.rs @@ -16,51 +16,7 @@ use crate::io; use crate::task::{Context, Poll}; extension_trait! { - #[doc = r#" - Allows reading from a buffered byte stream. - - This trait is a re-export of [`futures::io::AsyncBufRead`] and is an async version of - [`std::io::BufRead`]. - - The [provided methods] do not really exist in the trait itself, but they become - available when [`BufReadExt`] from the [prelude] is imported: - - ``` - # #[allow(unused_imports)] - use async_std::io::prelude::*; - ``` - - [`std::io::BufRead`]: https://doc.rust-lang.org/std/io/trait.BufRead.html - [`futures::io::AsyncBufRead`]: - https://docs.rs/futures/0.3/futures/io/trait.AsyncBufRead.html - [provided methods]: #provided-methods - [`BufReadExt`]: ../io/prelude/trait.BufReadExt.html - [prelude]: ../prelude/index.html - "#] - pub trait BufRead { - #[doc = r#" - Returns the contents of the internal buffer, filling it with more data from the - inner reader if it is empty. - - This function is a lower-level call. It needs to be paired with the [`consume`] - method to function properly. When calling this method, none of the contents will be - "read" in the sense that later calling `read` may return the same contents. As - such, [`consume`] must be called with the number of bytes that are consumed from - this buffer to ensure that the bytes are never returned twice. - - [`consume`]: #tymethod.consume - - An empty buffer returned indicates that the stream has reached EOF. - "#] - // TODO: write a proper doctest with `consume` - fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll>; - - #[doc = r#" - Tells this buffer that `amt` bytes have been consumed from the buffer, so they - should no longer be returned in calls to `read`. - "#] - fn consume(self: Pin<&mut Self>, amt: usize); - } + pub trait BufRead {} #[doc = r#" Extension methods for [`BufRead`]. diff --git a/src/io/read/mod.rs b/src/io/read/mod.rs index 8c6d3a3e..12c7960e 100644 --- a/src/io/read/mod.rs +++ b/src/io/read/mod.rs @@ -22,49 +22,7 @@ pub use chain::Chain; pub use take::Take; extension_trait! { - #[doc = r#" - Allows reading from a byte stream. - - This trait is a re-export of [`futures::io::AsyncRead`] and is an async version of - [`std::io::Read`]. - - Methods other than [`poll_read`] and [`poll_read_vectored`] do not really exist in the - trait itself, but they become available when [`ReadExt`] from the [prelude] is imported: - - ``` - # #[allow(unused_imports)] - use async_std::prelude::*; - ``` - - [`std::io::Read`]: https://doc.rust-lang.org/std/io/trait.Read.html - [`futures::io::AsyncRead`]: - https://docs.rs/futures/0.3/futures/io/trait.AsyncRead.html - [`poll_read`]: #tymethod.poll_read - [`poll_read_vectored`]: #method.poll_read_vectored - [`ReadExt`]: ../io/prelude/trait.ReadExt.html - [prelude]: ../prelude/index.html - "#] - pub trait Read { - #[doc = r#" - Attempt to read from the `AsyncRead` into `buf`. - "#] - fn poll_read( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - buf: &mut [u8], - ) -> Poll>; - - #[doc = r#" - Attempt to read from the `AsyncRead` into `bufs` using vectored IO operations. - "#] - fn poll_read_vectored( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - bufs: &mut [IoSliceMut<'_>], - ) -> Poll> { - unreachable!("this impl only appears in the rendered docs") - } - } + pub trait Read {} #[doc = r#" Extension methods for [`Read`]. diff --git a/src/io/seek/mod.rs b/src/io/seek/mod.rs index 748a1ed9..c5ca6c61 100644 --- a/src/io/seek/mod.rs +++ b/src/io/seek/mod.rs @@ -5,37 +5,7 @@ use seek::SeekFuture; use crate::io::SeekFrom; extension_trait! { - #[doc = r#" - Allows seeking through a byte stream. - - This trait is a re-export of [`futures::io::AsyncSeek`] and is an async version of - [`std::io::Seek`]. - - The [provided methods] do not really exist in the trait itself, but they become - available when [`SeekExt`] the [prelude] is imported: - - ``` - # #[allow(unused_imports)] - use async_std::prelude::*; - ``` - - [`std::io::Seek`]: https://doc.rust-lang.org/std/io/trait.Seek.html - [`futures::io::AsyncSeek`]: - https://docs.rs/futures/0.3/futures/io/trait.AsyncSeek.html - [provided methods]: #provided-methods - [`SeekExt`]: ../io/prelude/trait.SeekExt.html - [prelude]: ../prelude/index.html - "#] - pub trait Seek { - #[doc = r#" - Attempt to seek to an offset, in bytes, in a stream. - "#] - fn poll_seek( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - pos: SeekFrom, - ) -> Poll>; - } + pub trait Seek {} #[doc = r#" Extension methods for [`Seek`]. diff --git a/src/io/write/mod.rs b/src/io/write/mod.rs index b0ed8eec..d000ad7c 100644 --- a/src/io/write/mod.rs +++ b/src/io/write/mod.rs @@ -13,63 +13,7 @@ use write_vectored::WriteVectoredFuture; use crate::io::{self, IoSlice}; extension_trait! { - #[doc = r#" - Allows writing to a byte stream. - - This trait is a re-export of [`futures::io::AsyncWrite`] and is an async version of - [`std::io::Write`]. - - Methods other than [`poll_write`], [`poll_write_vectored`], [`poll_flush`], and - [`poll_close`] do not really exist in the trait itself, but they become available when - [`WriteExt`] from the [prelude] is imported: - - ``` - # #[allow(unused_imports)] - use async_std::prelude::*; - ``` - - [`std::io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html - [`futures::io::AsyncWrite`]: - https://docs.rs/futures/0.3/futures/io/trait.AsyncWrite.html - [`poll_write`]: #tymethod.poll_write - [`poll_write_vectored`]: #method.poll_write_vectored - [`poll_flush`]: #tymethod.poll_flush - [`poll_close`]: #tymethod.poll_close - [`WriteExt`]: ../io/prelude/trait.WriteExt.html - [prelude]: ../prelude/index.html - "#] - pub trait Write { - #[doc = r#" - Attempt to write bytes from `buf` into the object. - "#] - fn poll_write( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - buf: &[u8], - ) -> Poll>; - - #[doc = r#" - Attempt to write bytes from `bufs` into the object using vectored IO operations. - "#] - fn poll_write_vectored( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - bufs: &[IoSlice<'_>] - ) -> Poll> { - unreachable!("this impl only appears in the rendered docs") - } - - #[doc = r#" - Attempt to flush the object, ensuring that any buffered data reach - their destination. - "#] - fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll>; - - #[doc = r#" - Attempt to close the object. - "#] - fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll>; - } + pub trait Write {} #[doc = r#" Extension methods for [`Write`]. diff --git a/src/stream/stream/mod.rs b/src/stream/stream/mod.rs index 90c5cb7a..a316893d 100644 --- a/src/stream/stream/mod.rs +++ b/src/stream/stream/mod.rs @@ -144,86 +144,7 @@ cfg_unstable! { } extension_trait! { - #[doc = r#" - An asynchronous stream of values. - - This trait is a re-export of [`futures::stream::Stream`] and is an async version of - [`std::iter::Iterator`]. - - The [provided methods] do not really exist in the trait itself, but they become - available when [`StreamExt`] from the [prelude] is imported: - - ``` - # #[allow(unused_imports)] - use async_std::prelude::*; - ``` - - [`std::iter::Iterator`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html - [`futures::stream::Stream`]: - https://docs.rs/futures/0.3/futures/stream/trait.Stream.html - [provided methods]: #provided-methods - [`StreamExt`]: ../prelude/trait.StreamExt.html - [prelude]: ../prelude/index.html - "#] - pub trait Stream { - #[doc = r#" - The type of items yielded by this stream. - "#] - type Item; - - #[doc = r#" - Attempts to receive the next item from the stream. - - There are several possible return values: - - * `Poll::Pending` means this stream's next value is not ready yet. - * `Poll::Ready(None)` means this stream has been exhausted. - * `Poll::Ready(Some(item))` means `item` was received out of the stream. - - # Examples - - ``` - # fn main() { async_std::task::block_on(async { - # - use std::pin::Pin; - - use async_std::prelude::*; - use async_std::stream; - use async_std::task::{Context, Poll}; - - fn increment( - s: impl Stream + Unpin, - ) -> impl Stream + Unpin { - struct Increment(S); - - impl + Unpin> Stream for Increment { - type Item = S::Item; - - fn poll_next( - mut self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll> { - match Pin::new(&mut self.0).poll_next(cx) { - Poll::Pending => Poll::Pending, - Poll::Ready(None) => Poll::Ready(None), - Poll::Ready(Some(item)) => Poll::Ready(Some(item + 1)), - } - } - } - - Increment(s) - } - - let mut s = increment(stream::once(7)); - - assert_eq!(s.next().await, Some(8)); - assert_eq!(s.next().await, None); - # - # }) } - ``` - "#] - fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll>; - } + pub trait Stream {} #[doc = r#" Extension methods for [`Stream`]. diff --git a/src/utils.rs b/src/utils.rs index 8b8ee23f..42286ad1 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -250,10 +250,7 @@ macro_rules! extension_trait { // - `$name`: trait name that gets rendered in the docs // - `$ext`: name of the hidden extension trait // - `$base`: base trait - #[doc = $doc:tt] - pub trait $name:ident { - $($body_base:tt)* - } + pub trait $name:ident {} #[doc = $doc_ext:tt] pub trait $ext:ident: $base:path { From 6b3667d1a49adc8a666ed27d4331e085f0f766e3 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 11 Mar 2022 12:10:13 +1100 Subject: [PATCH 05/11] Remove unnecessary types in `extension_trait`. The remaining type requires the square brackets (for now) because a `ty` cannot immediately precede a `$(tt)*`. --- src/future/future/mod.rs | 15 +++++----- src/io/buf_read/mod.rs | 4 +-- src/io/read/mod.rs | 10 +++---- src/io/seek/mod.rs | 2 +- src/io/write/mod.rs | 10 +++---- src/stream/stream/mod.rs | 64 ++++++++++++++++++++-------------------- src/utils.rs | 2 +- 7 files changed, 53 insertions(+), 54 deletions(-) diff --git a/src/future/future/mod.rs b/src/future/future/mod.rs index a913f4fc..46780f8c 100644 --- a/src/future/future/mod.rs +++ b/src/future/future/mod.rs @@ -45,7 +45,7 @@ extension_trait! { /// ``` #[cfg(feature = "unstable")] #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - fn delay(self, dur: Duration) -> impl Future [DelayFuture] + fn delay(self, dur: Duration) -> [DelayFuture] where Self: Sized, { @@ -70,8 +70,7 @@ extension_trait! { #[cfg_attr(feature = "docs", doc(cfg(unstable)))] fn flatten( self, - ) -> impl Future::Output> - [FlattenFuture::Future>] + ) -> [FlattenFuture::Future>] where Self: Sized, ::Output: IntoFuture, @@ -113,7 +112,7 @@ extension_trait! { fn race( self, other: F, - ) -> impl Future::Output> [Race] + ) -> [Race] where Self: std::future::Future + Sized, F: std::future::Future::Output>, @@ -159,7 +158,7 @@ extension_trait! { fn try_race( self, other: F - ) -> impl Future::Output> [TryRace] + ) -> [TryRace] where Self: std::future::Future> + Sized, F: std::future::Future::Output>, @@ -196,7 +195,7 @@ extension_trait! { fn join( self, other: F - ) -> impl Future::Output, ::Output)> [Join] + ) -> [Join] where Self: std::future::Future + Sized, F: std::future::Future, @@ -243,7 +242,7 @@ extension_trait! { fn try_join( self, other: F - ) -> impl Future> [TryJoin] + ) -> [TryJoin] where Self: std::future::Future> + Sized, F: std::future::Future>, @@ -279,7 +278,7 @@ extension_trait! { "#] #[cfg(any(all(feature = "default", feature = "unstable"), feature = "docs"))] #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - fn timeout(self, dur: Duration) -> impl Future [TimeoutFuture] + fn timeout(self, dur: Duration) -> [TimeoutFuture] where Self: Sized { TimeoutFuture::new(self, dur) diff --git a/src/io/buf_read/mod.rs b/src/io/buf_read/mod.rs index d42cbd8a..2b1ee86b 100644 --- a/src/io/buf_read/mod.rs +++ b/src/io/buf_read/mod.rs @@ -78,7 +78,7 @@ extension_trait! { &'a mut self, byte: u8, buf: &'a mut Vec, - ) -> impl Future [ReadUntilFuture<'a, Self>] + ) -> [ReadUntilFuture<'a, Self>] where Self: Unpin, { @@ -131,7 +131,7 @@ extension_trait! { fn read_line<'a>( &'a mut self, buf: &'a mut String, - ) -> impl Future> [ReadLineFuture<'a, Self>] + ) -> [ReadLineFuture<'a, Self>] where Self: Unpin, { diff --git a/src/io/read/mod.rs b/src/io/read/mod.rs index 12c7960e..601bb7f1 100644 --- a/src/io/read/mod.rs +++ b/src/io/read/mod.rs @@ -64,7 +64,7 @@ extension_trait! { fn read<'a>( &'a mut self, buf: &'a mut [u8], - ) -> impl Future> [ReadFuture<'a, Self>] + ) -> [ReadFuture<'a, Self>] where Self: Unpin { @@ -86,7 +86,7 @@ extension_trait! { fn read_vectored<'a>( &'a mut self, bufs: &'a mut [IoSliceMut<'a>], - ) -> impl Future> [ReadVectoredFuture<'a, Self>] + ) -> [ReadVectoredFuture<'a, Self>] where Self: Unpin, { @@ -123,7 +123,7 @@ extension_trait! { fn read_to_end<'a>( &'a mut self, buf: &'a mut Vec, - ) -> impl Future> [ReadToEndFuture<'a, Self>] + ) -> [ReadToEndFuture<'a, Self>] where Self: Unpin, { @@ -162,7 +162,7 @@ extension_trait! { fn read_to_string<'a>( &'a mut self, buf: &'a mut String, - ) -> impl Future> [ReadToStringFuture<'a, Self>] + ) -> [ReadToStringFuture<'a, Self>] where Self: Unpin, { @@ -217,7 +217,7 @@ extension_trait! { fn read_exact<'a>( &'a mut self, buf: &'a mut [u8], - ) -> impl Future> [ReadExactFuture<'a, Self>] + ) -> [ReadExactFuture<'a, Self>] where Self: Unpin, { diff --git a/src/io/seek/mod.rs b/src/io/seek/mod.rs index c5ca6c61..29723223 100644 --- a/src/io/seek/mod.rs +++ b/src/io/seek/mod.rs @@ -40,7 +40,7 @@ extension_trait! { fn seek( &mut self, pos: SeekFrom, - ) -> impl Future> [SeekFuture<'_, Self>] + ) -> [SeekFuture<'_, Self>] where Self: Unpin, { diff --git a/src/io/write/mod.rs b/src/io/write/mod.rs index d000ad7c..c8befae3 100644 --- a/src/io/write/mod.rs +++ b/src/io/write/mod.rs @@ -49,7 +49,7 @@ extension_trait! { fn write<'a>( &'a mut self, buf: &'a [u8], - ) -> impl Future> [WriteFuture<'a, Self>] + ) -> [WriteFuture<'a, Self>] where Self: Unpin, { @@ -75,7 +75,7 @@ extension_trait! { # Ok(()) }) } ``` "#] - fn flush(&mut self) -> impl Future> [FlushFuture<'_, Self>] + fn flush(&mut self) -> [FlushFuture<'_, Self>] where Self: Unpin, { @@ -97,7 +97,7 @@ extension_trait! { fn write_vectored<'a>( &'a mut self, bufs: &'a [IoSlice<'a>], - ) -> impl Future> [WriteVectoredFuture<'a, Self>] + ) -> [WriteVectoredFuture<'a, Self>] where Self: Unpin, { @@ -133,7 +133,7 @@ extension_trait! { fn write_all<'a>( &'a mut self, buf: &'a [u8], - ) -> impl Future> [WriteAllFuture<'a, Self>] + ) -> [WriteAllFuture<'a, Self>] where Self: Unpin, { @@ -170,7 +170,7 @@ extension_trait! { fn write_fmt<'a>( &'a mut self, fmt: std::fmt::Arguments<'_>, - ) -> impl Future> [WriteFmtFuture<'a, Self>] + ) -> [WriteFmtFuture<'a, Self>] where Self: Unpin, { diff --git a/src/stream/stream/mod.rs b/src/stream/stream/mod.rs index a316893d..d71dc609 100644 --- a/src/stream/stream/mod.rs +++ b/src/stream/stream/mod.rs @@ -177,7 +177,7 @@ extension_trait! { # }) } ``` "#] - fn next(&mut self) -> impl Future> [NextFuture<'_, Self>] + fn next(&mut self) -> [NextFuture<'_, Self>] where Self: Unpin, { @@ -629,7 +629,7 @@ extension_trait! { "#] fn last( self, - ) -> impl Future> [LastFuture] + ) -> [LastFuture] where Self: Sized, { @@ -839,7 +839,7 @@ extension_trait! { fn min_by_key( self, key_by: F, - ) -> impl Future> [MinByKeyFuture] + ) -> [MinByKeyFuture] where Self: Sized, B: Ord, @@ -875,7 +875,7 @@ extension_trait! { fn max_by_key( self, key_by: F, - ) -> impl Future> [MaxByKeyFuture] + ) -> [MaxByKeyFuture] where Self: Sized, B: Ord, @@ -914,7 +914,7 @@ extension_trait! { fn min_by( self, compare: F, - ) -> impl Future> [MinByFuture] + ) -> [MinByFuture] where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering, @@ -947,7 +947,7 @@ extension_trait! { "#] fn max( self, - ) -> impl Future> [MaxFuture] + ) -> [MaxFuture] where Self: Sized, Self::Item: Ord, @@ -980,7 +980,7 @@ extension_trait! { "#] fn min( self, - ) -> impl Future> [MinFuture] + ) -> [MinFuture] where Self: Sized, Self::Item: Ord, @@ -1018,7 +1018,7 @@ extension_trait! { fn max_by( self, compare: F, - ) -> impl Future> [MaxByFuture] + ) -> [MaxByFuture] where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering, @@ -1082,7 +1082,7 @@ extension_trait! { fn nth( &mut self, n: usize, - ) -> impl Future> [NthFuture<'_, Self>] + ) -> [NthFuture<'_, Self>] where Self: Unpin + Sized, { @@ -1138,7 +1138,7 @@ extension_trait! { fn all( &mut self, f: F, - ) -> impl Future [AllFuture<'_, Self, F, Self::Item>] + ) -> [AllFuture<'_, Self, F, Self::Item>] where Self: Unpin + Sized, F: FnMut(Self::Item) -> bool, @@ -1187,7 +1187,7 @@ extension_trait! { fn find

( &mut self, p: P, - ) -> impl Future> [FindFuture<'_, Self, P>] + ) -> [FindFuture<'_, Self, P>] where Self: Unpin + Sized, P: FnMut(&Self::Item) -> bool, @@ -1215,7 +1215,7 @@ extension_trait! { fn find_map( &mut self, f: F, - ) -> impl Future> [FindMapFuture<'_, Self, F>] + ) -> [FindMapFuture<'_, Self, F>] where Self: Unpin + Sized, F: FnMut(Self::Item) -> Option, @@ -1249,7 +1249,7 @@ extension_trait! { self, init: B, f: F, - ) -> impl Future [FoldFuture] + ) -> [FoldFuture] where Self: Sized, F: FnMut(B, Self::Item) -> B, @@ -1286,7 +1286,7 @@ extension_trait! { fn partition( self, f: F, - ) -> impl Future [PartitionFuture] + ) -> [PartitionFuture] where Self: Sized, F: FnMut(&Self::Item) -> bool, @@ -1322,7 +1322,7 @@ extension_trait! { fn for_each( self, f: F, - ) -> impl Future [ForEachFuture] + ) -> [ForEachFuture] where Self: Sized, F: FnMut(Self::Item), @@ -1378,7 +1378,7 @@ extension_trait! { fn any( &mut self, f: F, - ) -> impl Future [AnyFuture<'_, Self, F, Self::Item>] + ) -> [AnyFuture<'_, Self, F, Self::Item>] where Self: Unpin + Sized, F: FnMut(Self::Item) -> bool, @@ -1614,7 +1614,7 @@ extension_trait! { &mut self, init: T, f: F, - ) -> impl Future> [TryFoldFuture<'_, Self, F, T>] + ) -> [TryFoldFuture<'_, Self, F, T>] where Self: Unpin + Sized, F: FnMut(B, Self::Item) -> Result, @@ -1659,7 +1659,7 @@ extension_trait! { fn try_for_each( &mut self, f: F, - ) -> impl Future [TryForEachFuture<'_, Self, F>] + ) -> [TryForEachFuture<'_, Self, F>] where Self: Unpin + Sized, F: FnMut(Self::Item) -> Result<(), E>, @@ -1741,7 +1741,7 @@ extension_trait! { "#] #[cfg(feature = "unstable")] #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - fn unzip(self) -> impl Future [UnzipFuture] + fn unzip(self) -> [UnzipFuture] where FromA: Default + Extend, FromB: Default + Extend, @@ -1805,7 +1805,7 @@ extension_trait! { #[cfg_attr(feature = "docs", doc(cfg(unstable)))] fn collect<'a, B>( self, - ) -> impl Future [Pin + 'a + Send>>] + ) -> [Pin + 'a + Send>>] where Self: Sized + 'a + Send, B: FromStream, @@ -1879,7 +1879,7 @@ extension_trait! { fn partial_cmp( self, other: S - ) -> impl Future> [PartialCmpFuture] + ) -> [PartialCmpFuture] where Self: Sized + Stream, S: Stream, @@ -1919,7 +1919,7 @@ extension_trait! { fn position

( &mut self, predicate: P, - ) -> impl Future> [PositionFuture<'_, Self, P>] + ) -> [PositionFuture<'_, Self, P>] where Self: Unpin + Sized, P: FnMut(Self::Item) -> bool, @@ -1957,7 +1957,7 @@ extension_trait! { fn cmp( self, other: S - ) -> impl Future [CmpFuture] + ) -> [CmpFuture] where Self: Sized + Stream, S: Stream, @@ -1988,7 +1988,7 @@ extension_trait! { "#] #[cfg(feature = "unstable")] #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - fn count(self) -> impl Future [CountFuture] + fn count(self) -> [CountFuture] where Self: Sized, { @@ -2023,7 +2023,7 @@ extension_trait! { fn ne( self, other: S - ) -> impl Future [NeFuture] + ) -> [NeFuture] where Self: Sized, S: Sized + Stream, @@ -2060,7 +2060,7 @@ extension_trait! { fn ge( self, other: S - ) -> impl Future [GeFuture] + ) -> [GeFuture] where Self: Sized + Stream, S: Stream, @@ -2097,7 +2097,7 @@ extension_trait! { fn eq( self, other: S - ) -> impl Future [EqFuture] + ) -> [EqFuture] where Self: Sized + Stream, S: Sized + Stream, @@ -2134,7 +2134,7 @@ extension_trait! { fn gt( self, other: S - ) -> impl Future [GtFuture] + ) -> [GtFuture] where Self: Sized + Stream, S: Stream, @@ -2171,7 +2171,7 @@ extension_trait! { fn le( self, other: S - ) -> impl Future [LeFuture] + ) -> [LeFuture] where Self: Sized + Stream, S: Stream, @@ -2208,7 +2208,7 @@ extension_trait! { fn lt( self, other: S - ) -> impl Future [LtFuture] + ) -> [LtFuture] where Self: Sized + Stream, S: Stream, @@ -2252,7 +2252,7 @@ extension_trait! { #[cfg_attr(feature = "docs", doc(cfg(unstable)))] fn sum<'a, S>( self, - ) -> impl Future [Pin + 'a>>] + ) -> [Pin + 'a>>] where Self: Sized + Stream + 'a, S: Sum, @@ -2298,7 +2298,7 @@ extension_trait! { #[cfg_attr(feature = "docs", doc(cfg(unstable)))] fn product<'a, P>( self, - ) -> impl Future [Pin + 'a>>] + ) -> [Pin + 'a>>] where Self: Sized + Stream + 'a, P: Product, diff --git a/src/utils.rs b/src/utils.rs index 42286ad1..1f3b7fc8 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -271,7 +271,7 @@ macro_rules! extension_trait { }; // Parse the return type in an extension method. - (@ext [-> impl Future [$f:ty] $($tail:tt)*] -> [$($accum:tt)*]) => { + (@ext [-> [$f:ty] $($tail:tt)*] -> [$($accum:tt)*]) => { extension_trait!(@ext [$($tail)*] -> [$($accum)* -> $f]); }; From c626a696706020e5e0cc018db8ea468ea165f529 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 11 Mar 2022 12:20:23 +1100 Subject: [PATCH 06/11] Move the blanket `impl` outside of `extension_trait`. --- src/future/future/mod.rs | 3 +++ src/io/buf_read/mod.rs | 2 ++ src/io/read/mod.rs | 3 ++- src/io/seek/mod.rs | 2 ++ src/io/write/mod.rs | 2 ++ src/stream/stream/mod.rs | 3 +++ src/utils.rs | 3 --- 7 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/future/future/mod.rs b/src/future/future/mod.rs index 46780f8c..05d099b0 100644 --- a/src/future/future/mod.rs +++ b/src/future/future/mod.rs @@ -285,3 +285,6 @@ extension_trait! { } } } + +impl FutureExt for T {} + diff --git a/src/io/buf_read/mod.rs b/src/io/buf_read/mod.rs index 2b1ee86b..1314dc9f 100644 --- a/src/io/buf_read/mod.rs +++ b/src/io/buf_read/mod.rs @@ -239,6 +239,8 @@ extension_trait! { } } +impl BufReadExt for T {} + pub fn read_until_internal( mut reader: Pin<&mut R>, cx: &mut Context<'_>, diff --git a/src/io/read/mod.rs b/src/io/read/mod.rs index 601bb7f1..9b5b9644 100644 --- a/src/io/read/mod.rs +++ b/src/io/read/mod.rs @@ -372,10 +372,11 @@ extension_trait! { fn chain(self, next: R) -> Chain where Self: Sized { Chain { first: self, second: next, done_first: false } } - } } +impl ReadExt for T {} + /// Initializes a buffer if necessary. /// /// Currently, a buffer is always initialized because `read_initializer` diff --git a/src/io/seek/mod.rs b/src/io/seek/mod.rs index 29723223..33ba25e3 100644 --- a/src/io/seek/mod.rs +++ b/src/io/seek/mod.rs @@ -48,3 +48,5 @@ extension_trait! { } } } + +impl SeekExt for T {} diff --git a/src/io/write/mod.rs b/src/io/write/mod.rs index c8befae3..3463d282 100644 --- a/src/io/write/mod.rs +++ b/src/io/write/mod.rs @@ -185,3 +185,5 @@ extension_trait! { } } } + +impl WriteExt for T {} diff --git a/src/stream/stream/mod.rs b/src/stream/stream/mod.rs index d71dc609..279a8369 100644 --- a/src/stream/stream/mod.rs +++ b/src/stream/stream/mod.rs @@ -2307,3 +2307,6 @@ extension_trait! { } } } + +impl StreamExt for T {} + diff --git a/src/utils.rs b/src/utils.rs index 1f3b7fc8..51b2fb0c 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -265,9 +265,6 @@ macro_rules! extension_trait { pub trait $ext: $name { extension_trait!(@ext [$($body_ext)*] -> []); } - - // Blanket implementation of the extension trait for any type implementing the base trait. - impl $ext for T {} }; // Parse the return type in an extension method. From 1c70420c5a1346d2162155ad0782bf86786b4767 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 11 Mar 2022 12:24:15 +1100 Subject: [PATCH 07/11] Move the base trait re-export outside of `extension_trait`. --- src/future/future/mod.rs | 2 ++ src/io/buf_read/mod.rs | 2 ++ src/io/read/mod.rs | 2 ++ src/io/seek/mod.rs | 2 ++ src/io/write/mod.rs | 2 ++ src/stream/stream/mod.rs | 2 ++ src/utils.rs | 3 --- 7 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/future/future/mod.rs b/src/future/future/mod.rs index 05d099b0..d6c4d7e0 100644 --- a/src/future/future/mod.rs +++ b/src/future/future/mod.rs @@ -20,6 +20,8 @@ cfg_unstable_default! { use crate::future::timeout::TimeoutFuture; } +pub use core::future::Future as Future; + extension_trait! { pub trait Future {} diff --git a/src/io/buf_read/mod.rs b/src/io/buf_read/mod.rs index 1314dc9f..82917156 100644 --- a/src/io/buf_read/mod.rs +++ b/src/io/buf_read/mod.rs @@ -15,6 +15,8 @@ use std::pin::Pin; use crate::io; use crate::task::{Context, Poll}; +pub use futures_io::AsyncBufRead as BufRead; + extension_trait! { pub trait BufRead {} diff --git a/src/io/read/mod.rs b/src/io/read/mod.rs index 9b5b9644..b8855886 100644 --- a/src/io/read/mod.rs +++ b/src/io/read/mod.rs @@ -21,6 +21,8 @@ pub use bytes::Bytes; pub use chain::Chain; pub use take::Take; +pub use futures_io::AsyncRead as Read; + extension_trait! { pub trait Read {} diff --git a/src/io/seek/mod.rs b/src/io/seek/mod.rs index 33ba25e3..cafbfe62 100644 --- a/src/io/seek/mod.rs +++ b/src/io/seek/mod.rs @@ -4,6 +4,8 @@ use seek::SeekFuture; use crate::io::SeekFrom; +pub use futures_io::AsyncSeek as Seek; + extension_trait! { pub trait Seek {} diff --git a/src/io/write/mod.rs b/src/io/write/mod.rs index 3463d282..6e9a574f 100644 --- a/src/io/write/mod.rs +++ b/src/io/write/mod.rs @@ -12,6 +12,8 @@ use write_vectored::WriteVectoredFuture; use crate::io::{self, IoSlice}; +pub use futures_io::AsyncWrite as Write; + extension_trait! { pub trait Write {} diff --git a/src/stream/stream/mod.rs b/src/stream/stream/mod.rs index 279a8369..48fdbb22 100644 --- a/src/stream/stream/mod.rs +++ b/src/stream/stream/mod.rs @@ -143,6 +143,8 @@ cfg_unstable! { mod unzip; } +pub use futures_core::stream::Stream as Stream; + extension_trait! { pub trait Stream {} diff --git a/src/utils.rs b/src/utils.rs index 51b2fb0c..d662e17f 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -257,9 +257,6 @@ macro_rules! extension_trait { $($body_ext:tt)* } ) => { - // Re-export the base trait from the futures crate. - pub use $base as $name; - // The extension trait that adds methods to any type implementing the base trait. #[doc = $doc_ext] pub trait $ext: $name { From 2dde8820fa2b108db011166467f20cabb4627b69 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 11 Mar 2022 12:27:23 +1100 Subject: [PATCH 08/11] Remove what's left of the first trait in `extension_trait`. --- src/future/future/mod.rs | 4 +--- src/io/buf_read/mod.rs | 4 +--- src/io/read/mod.rs | 4 +--- src/io/seek/mod.rs | 4 +--- src/io/write/mod.rs | 4 +--- src/stream/stream/mod.rs | 4 +--- src/utils.rs | 8 +------- 7 files changed, 7 insertions(+), 25 deletions(-) diff --git a/src/future/future/mod.rs b/src/future/future/mod.rs index d6c4d7e0..e20f8bac 100644 --- a/src/future/future/mod.rs +++ b/src/future/future/mod.rs @@ -23,14 +23,12 @@ cfg_unstable_default! { pub use core::future::Future as Future; extension_trait! { - pub trait Future {} - #[doc = r#" Extension methods for [`Future`]. [`Future`]: ../future/trait.Future.html "#] - pub trait FutureExt: core::future::Future { + pub trait FutureExt: Future { /// Returns a Future that delays execution for a specified time. /// /// # Examples diff --git a/src/io/buf_read/mod.rs b/src/io/buf_read/mod.rs index 82917156..8f248e2b 100644 --- a/src/io/buf_read/mod.rs +++ b/src/io/buf_read/mod.rs @@ -18,14 +18,12 @@ use crate::task::{Context, Poll}; pub use futures_io::AsyncBufRead as BufRead; extension_trait! { - pub trait BufRead {} - #[doc = r#" Extension methods for [`BufRead`]. [`BufRead`]: ../trait.BufRead.html "#] - pub trait BufReadExt: futures_io::AsyncBufRead { + pub trait BufReadExt: BufRead { #[doc = r#" Reads all bytes into `buf` until the delimiter `byte` or EOF is reached. diff --git a/src/io/read/mod.rs b/src/io/read/mod.rs index b8855886..f96b8154 100644 --- a/src/io/read/mod.rs +++ b/src/io/read/mod.rs @@ -24,14 +24,12 @@ pub use take::Take; pub use futures_io::AsyncRead as Read; extension_trait! { - pub trait Read {} - #[doc = r#" Extension methods for [`Read`]. [`Read`]: ../trait.Read.html "#] - pub trait ReadExt: futures_io::AsyncRead { + pub trait ReadExt: Read { #[doc = r#" Reads some bytes from the byte stream. diff --git a/src/io/seek/mod.rs b/src/io/seek/mod.rs index cafbfe62..af7cafcf 100644 --- a/src/io/seek/mod.rs +++ b/src/io/seek/mod.rs @@ -7,14 +7,12 @@ use crate::io::SeekFrom; pub use futures_io::AsyncSeek as Seek; extension_trait! { - pub trait Seek {} - #[doc = r#" Extension methods for [`Seek`]. [`Seek`]: ../trait.Seek.html "#] - pub trait SeekExt: futures_io::AsyncSeek { + pub trait SeekExt: Seek { #[doc = r#" Seeks to a new position in a byte stream. diff --git a/src/io/write/mod.rs b/src/io/write/mod.rs index 6e9a574f..b18d80f0 100644 --- a/src/io/write/mod.rs +++ b/src/io/write/mod.rs @@ -15,14 +15,12 @@ use crate::io::{self, IoSlice}; pub use futures_io::AsyncWrite as Write; extension_trait! { - pub trait Write {} - #[doc = r#" Extension methods for [`Write`]. [`Write`]: ../trait.Write.html "#] - pub trait WriteExt: futures_io::AsyncWrite { + pub trait WriteExt: Write { #[doc = r#" Writes some bytes into the byte stream. diff --git a/src/stream/stream/mod.rs b/src/stream/stream/mod.rs index 48fdbb22..0ead0800 100644 --- a/src/stream/stream/mod.rs +++ b/src/stream/stream/mod.rs @@ -146,14 +146,12 @@ cfg_unstable! { pub use futures_core::stream::Stream as Stream; extension_trait! { - pub trait Stream {} - #[doc = r#" Extension methods for [`Stream`]. [`Stream`]: ../stream/trait.Stream.html "#] - pub trait StreamExt: futures_core::stream::Stream { + pub trait StreamExt: Stream { #[doc = r#" Advances the stream and returns the next value. diff --git a/src/utils.rs b/src/utils.rs index d662e17f..96f24fd2 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -246,14 +246,8 @@ macro_rules! cfg_default { #[doc(hidden)] macro_rules! extension_trait { ( - // Interesting patterns: - // - `$name`: trait name that gets rendered in the docs - // - `$ext`: name of the hidden extension trait - // - `$base`: base trait - pub trait $name:ident {} - #[doc = $doc_ext:tt] - pub trait $ext:ident: $base:path { + pub trait $ext:ident: $name:ident { $($body_ext:tt)* } ) => { From 1146c66f1b9448a31d3a4f486e2ea9b372f0335c Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 11 Mar 2022 12:34:22 +1100 Subject: [PATCH 09/11] Remove `extension_trait`. At this point, `extension_trait` is basically an expensive no-op. This commit removes it. The next commit will adjust the indentation. --- src/future/future/mod.rs | 16 +++++----- src/io/buf_read/mod.rs | 6 ++-- src/io/read/mod.rs | 12 +++----- src/io/seek/mod.rs | 4 +-- src/io/write/mod.rs | 12 +++----- src/stream/stream/mod.rs | 66 +++++++++++++++++++--------------------- src/utils.rs | 38 ----------------------- 7 files changed, 52 insertions(+), 102 deletions(-) diff --git a/src/future/future/mod.rs b/src/future/future/mod.rs index e20f8bac..a244c285 100644 --- a/src/future/future/mod.rs +++ b/src/future/future/mod.rs @@ -22,7 +22,6 @@ cfg_unstable_default! { pub use core::future::Future as Future; -extension_trait! { #[doc = r#" Extension methods for [`Future`]. @@ -45,7 +44,7 @@ extension_trait! { /// ``` #[cfg(feature = "unstable")] #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - fn delay(self, dur: Duration) -> [DelayFuture] + fn delay(self, dur: Duration) -> DelayFuture where Self: Sized, { @@ -70,7 +69,7 @@ extension_trait! { #[cfg_attr(feature = "docs", doc(cfg(unstable)))] fn flatten( self, - ) -> [FlattenFuture::Future>] + ) -> FlattenFuture::Future> where Self: Sized, ::Output: IntoFuture, @@ -112,7 +111,7 @@ extension_trait! { fn race( self, other: F, - ) -> [Race] + ) -> Race where Self: std::future::Future + Sized, F: std::future::Future::Output>, @@ -158,7 +157,7 @@ extension_trait! { fn try_race( self, other: F - ) -> [TryRace] + ) -> TryRace where Self: std::future::Future> + Sized, F: std::future::Future::Output>, @@ -195,7 +194,7 @@ extension_trait! { fn join( self, other: F - ) -> [Join] + ) -> Join where Self: std::future::Future + Sized, F: std::future::Future, @@ -242,7 +241,7 @@ extension_trait! { fn try_join( self, other: F - ) -> [TryJoin] + ) -> TryJoin where Self: std::future::Future> + Sized, F: std::future::Future>, @@ -278,13 +277,12 @@ extension_trait! { "#] #[cfg(any(all(feature = "default", feature = "unstable"), feature = "docs"))] #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - fn timeout(self, dur: Duration) -> [TimeoutFuture] + fn timeout(self, dur: Duration) -> TimeoutFuture where Self: Sized { TimeoutFuture::new(self, dur) } } -} impl FutureExt for T {} diff --git a/src/io/buf_read/mod.rs b/src/io/buf_read/mod.rs index 8f248e2b..f8bffaf3 100644 --- a/src/io/buf_read/mod.rs +++ b/src/io/buf_read/mod.rs @@ -17,7 +17,6 @@ use crate::task::{Context, Poll}; pub use futures_io::AsyncBufRead as BufRead; -extension_trait! { #[doc = r#" Extension methods for [`BufRead`]. @@ -78,7 +77,7 @@ extension_trait! { &'a mut self, byte: u8, buf: &'a mut Vec, - ) -> [ReadUntilFuture<'a, Self>] + ) -> ReadUntilFuture<'a, Self> where Self: Unpin, { @@ -131,7 +130,7 @@ extension_trait! { fn read_line<'a>( &'a mut self, buf: &'a mut String, - ) -> [ReadLineFuture<'a, Self>] + ) -> ReadLineFuture<'a, Self> where Self: Unpin, { @@ -237,7 +236,6 @@ extension_trait! { } } } -} impl BufReadExt for T {} diff --git a/src/io/read/mod.rs b/src/io/read/mod.rs index f96b8154..0109a3ac 100644 --- a/src/io/read/mod.rs +++ b/src/io/read/mod.rs @@ -23,7 +23,6 @@ pub use take::Take; pub use futures_io::AsyncRead as Read; -extension_trait! { #[doc = r#" Extension methods for [`Read`]. @@ -64,7 +63,7 @@ extension_trait! { fn read<'a>( &'a mut self, buf: &'a mut [u8], - ) -> [ReadFuture<'a, Self>] + ) -> ReadFuture<'a, Self> where Self: Unpin { @@ -86,7 +85,7 @@ extension_trait! { fn read_vectored<'a>( &'a mut self, bufs: &'a mut [IoSliceMut<'a>], - ) -> [ReadVectoredFuture<'a, Self>] + ) -> ReadVectoredFuture<'a, Self> where Self: Unpin, { @@ -123,7 +122,7 @@ extension_trait! { fn read_to_end<'a>( &'a mut self, buf: &'a mut Vec, - ) -> [ReadToEndFuture<'a, Self>] + ) -> ReadToEndFuture<'a, Self> where Self: Unpin, { @@ -162,7 +161,7 @@ extension_trait! { fn read_to_string<'a>( &'a mut self, buf: &'a mut String, - ) -> [ReadToStringFuture<'a, Self>] + ) -> ReadToStringFuture<'a, Self> where Self: Unpin, { @@ -217,7 +216,7 @@ extension_trait! { fn read_exact<'a>( &'a mut self, buf: &'a mut [u8], - ) -> [ReadExactFuture<'a, Self>] + ) -> ReadExactFuture<'a, Self> where Self: Unpin, { @@ -373,7 +372,6 @@ extension_trait! { Chain { first: self, second: next, done_first: false } } } -} impl ReadExt for T {} diff --git a/src/io/seek/mod.rs b/src/io/seek/mod.rs index af7cafcf..f2b60932 100644 --- a/src/io/seek/mod.rs +++ b/src/io/seek/mod.rs @@ -6,7 +6,6 @@ use crate::io::SeekFrom; pub use futures_io::AsyncSeek as Seek; -extension_trait! { #[doc = r#" Extension methods for [`Seek`]. @@ -40,13 +39,12 @@ extension_trait! { fn seek( &mut self, pos: SeekFrom, - ) -> [SeekFuture<'_, Self>] + ) -> SeekFuture<'_, Self> where Self: Unpin, { SeekFuture { seeker: self, pos } } } -} impl SeekExt for T {} diff --git a/src/io/write/mod.rs b/src/io/write/mod.rs index b18d80f0..d73c40d8 100644 --- a/src/io/write/mod.rs +++ b/src/io/write/mod.rs @@ -14,7 +14,6 @@ use crate::io::{self, IoSlice}; pub use futures_io::AsyncWrite as Write; -extension_trait! { #[doc = r#" Extension methods for [`Write`]. @@ -49,7 +48,7 @@ extension_trait! { fn write<'a>( &'a mut self, buf: &'a [u8], - ) -> [WriteFuture<'a, Self>] + ) -> WriteFuture<'a, Self> where Self: Unpin, { @@ -75,7 +74,7 @@ extension_trait! { # Ok(()) }) } ``` "#] - fn flush(&mut self) -> [FlushFuture<'_, Self>] + fn flush(&mut self) -> FlushFuture<'_, Self> where Self: Unpin, { @@ -97,7 +96,7 @@ extension_trait! { fn write_vectored<'a>( &'a mut self, bufs: &'a [IoSlice<'a>], - ) -> [WriteVectoredFuture<'a, Self>] + ) -> WriteVectoredFuture<'a, Self> where Self: Unpin, { @@ -133,7 +132,7 @@ extension_trait! { fn write_all<'a>( &'a mut self, buf: &'a [u8], - ) -> [WriteAllFuture<'a, Self>] + ) -> WriteAllFuture<'a, Self> where Self: Unpin, { @@ -170,7 +169,7 @@ extension_trait! { fn write_fmt<'a>( &'a mut self, fmt: std::fmt::Arguments<'_>, - ) -> [WriteFmtFuture<'a, Self>] + ) -> WriteFmtFuture<'a, Self> where Self: Unpin, { @@ -184,6 +183,5 @@ extension_trait! { WriteFmtFuture { writer: self, res: Some(res), buffer: None, amt: 0 } } } -} impl WriteExt for T {} diff --git a/src/stream/stream/mod.rs b/src/stream/stream/mod.rs index 0ead0800..25aadfac 100644 --- a/src/stream/stream/mod.rs +++ b/src/stream/stream/mod.rs @@ -145,7 +145,6 @@ cfg_unstable! { pub use futures_core::stream::Stream as Stream; -extension_trait! { #[doc = r#" Extension methods for [`Stream`]. @@ -177,7 +176,7 @@ extension_trait! { # }) } ``` "#] - fn next(&mut self) -> [NextFuture<'_, Self>] + fn next(&mut self) -> NextFuture<'_, Self> where Self: Unpin, { @@ -629,7 +628,7 @@ extension_trait! { "#] fn last( self, - ) -> [LastFuture] + ) -> LastFuture where Self: Sized, { @@ -839,7 +838,7 @@ extension_trait! { fn min_by_key( self, key_by: F, - ) -> [MinByKeyFuture] + ) -> MinByKeyFuture where Self: Sized, B: Ord, @@ -875,7 +874,7 @@ extension_trait! { fn max_by_key( self, key_by: F, - ) -> [MaxByKeyFuture] + ) -> MaxByKeyFuture where Self: Sized, B: Ord, @@ -914,7 +913,7 @@ extension_trait! { fn min_by( self, compare: F, - ) -> [MinByFuture] + ) -> MinByFuture where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering, @@ -947,7 +946,7 @@ extension_trait! { "#] fn max( self, - ) -> [MaxFuture] + ) -> MaxFuture where Self: Sized, Self::Item: Ord, @@ -980,7 +979,7 @@ extension_trait! { "#] fn min( self, - ) -> [MinFuture] + ) -> MinFuture where Self: Sized, Self::Item: Ord, @@ -1018,7 +1017,7 @@ extension_trait! { fn max_by( self, compare: F, - ) -> [MaxByFuture] + ) -> MaxByFuture where Self: Sized, F: FnMut(&Self::Item, &Self::Item) -> Ordering, @@ -1082,7 +1081,7 @@ extension_trait! { fn nth( &mut self, n: usize, - ) -> [NthFuture<'_, Self>] + ) -> NthFuture<'_, Self> where Self: Unpin + Sized, { @@ -1138,7 +1137,7 @@ extension_trait! { fn all( &mut self, f: F, - ) -> [AllFuture<'_, Self, F, Self::Item>] + ) -> AllFuture<'_, Self, F, Self::Item> where Self: Unpin + Sized, F: FnMut(Self::Item) -> bool, @@ -1187,7 +1186,7 @@ extension_trait! { fn find

( &mut self, p: P, - ) -> [FindFuture<'_, Self, P>] + ) -> FindFuture<'_, Self, P> where Self: Unpin + Sized, P: FnMut(&Self::Item) -> bool, @@ -1215,7 +1214,7 @@ extension_trait! { fn find_map( &mut self, f: F, - ) -> [FindMapFuture<'_, Self, F>] + ) -> FindMapFuture<'_, Self, F> where Self: Unpin + Sized, F: FnMut(Self::Item) -> Option, @@ -1249,7 +1248,7 @@ extension_trait! { self, init: B, f: F, - ) -> [FoldFuture] + ) -> FoldFuture where Self: Sized, F: FnMut(B, Self::Item) -> B, @@ -1286,7 +1285,7 @@ extension_trait! { fn partition( self, f: F, - ) -> [PartitionFuture] + ) -> PartitionFuture where Self: Sized, F: FnMut(&Self::Item) -> bool, @@ -1322,7 +1321,7 @@ extension_trait! { fn for_each( self, f: F, - ) -> [ForEachFuture] + ) -> ForEachFuture where Self: Sized, F: FnMut(Self::Item), @@ -1378,7 +1377,7 @@ extension_trait! { fn any( &mut self, f: F, - ) -> [AnyFuture<'_, Self, F, Self::Item>] + ) -> AnyFuture<'_, Self, F, Self::Item> where Self: Unpin + Sized, F: FnMut(Self::Item) -> bool, @@ -1614,7 +1613,7 @@ extension_trait! { &mut self, init: T, f: F, - ) -> [TryFoldFuture<'_, Self, F, T>] + ) -> TryFoldFuture<'_, Self, F, T> where Self: Unpin + Sized, F: FnMut(B, Self::Item) -> Result, @@ -1659,7 +1658,7 @@ extension_trait! { fn try_for_each( &mut self, f: F, - ) -> [TryForEachFuture<'_, Self, F>] + ) -> TryForEachFuture<'_, Self, F> where Self: Unpin + Sized, F: FnMut(Self::Item) -> Result<(), E>, @@ -1741,7 +1740,7 @@ extension_trait! { "#] #[cfg(feature = "unstable")] #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - fn unzip(self) -> [UnzipFuture] + fn unzip(self) -> UnzipFuture where FromA: Default + Extend, FromB: Default + Extend, @@ -1805,7 +1804,7 @@ extension_trait! { #[cfg_attr(feature = "docs", doc(cfg(unstable)))] fn collect<'a, B>( self, - ) -> [Pin + 'a + Send>>] + ) -> Pin + 'a + Send>> where Self: Sized + 'a + Send, B: FromStream, @@ -1879,7 +1878,7 @@ extension_trait! { fn partial_cmp( self, other: S - ) -> [PartialCmpFuture] + ) -> PartialCmpFuture where Self: Sized + Stream, S: Stream, @@ -1919,7 +1918,7 @@ extension_trait! { fn position

( &mut self, predicate: P, - ) -> [PositionFuture<'_, Self, P>] + ) -> PositionFuture<'_, Self, P> where Self: Unpin + Sized, P: FnMut(Self::Item) -> bool, @@ -1957,7 +1956,7 @@ extension_trait! { fn cmp( self, other: S - ) -> [CmpFuture] + ) -> CmpFuture where Self: Sized + Stream, S: Stream, @@ -1988,7 +1987,7 @@ extension_trait! { "#] #[cfg(feature = "unstable")] #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - fn count(self) -> [CountFuture] + fn count(self) -> CountFuture where Self: Sized, { @@ -2023,7 +2022,7 @@ extension_trait! { fn ne( self, other: S - ) -> [NeFuture] + ) -> NeFuture where Self: Sized, S: Sized + Stream, @@ -2060,7 +2059,7 @@ extension_trait! { fn ge( self, other: S - ) -> [GeFuture] + ) -> GeFuture where Self: Sized + Stream, S: Stream, @@ -2097,7 +2096,7 @@ extension_trait! { fn eq( self, other: S - ) -> [EqFuture] + ) -> EqFuture where Self: Sized + Stream, S: Sized + Stream, @@ -2134,7 +2133,7 @@ extension_trait! { fn gt( self, other: S - ) -> [GtFuture] + ) -> GtFuture where Self: Sized + Stream, S: Stream, @@ -2171,7 +2170,7 @@ extension_trait! { fn le( self, other: S - ) -> [LeFuture] + ) -> LeFuture where Self: Sized + Stream, S: Stream, @@ -2208,7 +2207,7 @@ extension_trait! { fn lt( self, other: S - ) -> [LtFuture] + ) -> LtFuture where Self: Sized + Stream, S: Stream, @@ -2252,7 +2251,7 @@ extension_trait! { #[cfg_attr(feature = "docs", doc(cfg(unstable)))] fn sum<'a, S>( self, - ) -> [Pin + 'a>>] + ) -> Pin + 'a>> where Self: Sized + Stream + 'a, S: Sum, @@ -2298,7 +2297,7 @@ extension_trait! { #[cfg_attr(feature = "docs", doc(cfg(unstable)))] fn product<'a, P>( self, - ) -> [Pin + 'a>>] + ) -> Pin + 'a>> where Self: Sized + Stream + 'a, P: Product, @@ -2306,7 +2305,6 @@ extension_trait! { Product::product(self) } } -} impl StreamExt for T {} diff --git a/src/utils.rs b/src/utils.rs index 96f24fd2..d1b49727 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -233,41 +233,3 @@ macro_rules! cfg_default { )* } } - -/// Defines an extension trait for a base trait. -/// -/// In generated docs, the base trait will contain methods from the extension trait. In actual -/// code, the base trait will be re-exported and the extension trait will be hidden. We then -/// re-export the extension trait from the prelude. -/// -/// Inside invocations of this macro, we write a definitions that looks similar to the final -/// rendered docs, and the macro then generates all the boilerplate for us. -#[allow(unused_macros)] -#[doc(hidden)] -macro_rules! extension_trait { - ( - #[doc = $doc_ext:tt] - pub trait $ext:ident: $name:ident { - $($body_ext:tt)* - } - ) => { - // The extension trait that adds methods to any type implementing the base trait. - #[doc = $doc_ext] - pub trait $ext: $name { - extension_trait!(@ext [$($body_ext)*] -> []); - } - }; - - // Parse the return type in an extension method. - (@ext [-> [$f:ty] $($tail:tt)*] -> [$($accum:tt)*]) => { - extension_trait!(@ext [$($tail)*] -> [$($accum)* -> $f]); - }; - - // Parse a token. - (@ext [$token:tt $($tail:tt)*] -> [$($accum:tt)*]) => { - extension_trait!(@ext [$($tail)*] -> [$($accum)* $token]); - }; - - // Handle the end of the token list. - (@ext [] -> [$($accum:tt)*]) => { $($accum)* }; -} From 01ede03e0a68398d7a4b2bd0976750e078fd1a83 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 11 Mar 2022 12:40:05 +1100 Subject: [PATCH 10/11] Reindent de-macrofied code. This commit only affects whitespace; `git diff -w` for it is empty. --- src/future/future/mod.rs | 514 +++--- src/io/buf_read/mod.rs | 406 ++--- src/io/read/mod.rs | 564 +++--- src/io/seek/mod.rs | 72 +- src/io/write/mod.rs | 330 ++-- src/stream/stream/mod.rs | 3624 +++++++++++++++++++------------------- 6 files changed, 2755 insertions(+), 2755 deletions(-) diff --git a/src/future/future/mod.rs b/src/future/future/mod.rs index a244c285..47187b23 100644 --- a/src/future/future/mod.rs +++ b/src/future/future/mod.rs @@ -22,267 +22,267 @@ cfg_unstable_default! { pub use core::future::Future as Future; +#[doc = r#" + Extension methods for [`Future`]. + + [`Future`]: ../future/trait.Future.html +"#] +pub trait FutureExt: Future { + /// Returns a Future that delays execution for a specified time. + /// + /// # Examples + /// + /// ``` + /// # async_std::task::block_on(async { + /// use async_std::prelude::*; + /// use async_std::future; + /// use std::time::Duration; + /// + /// let a = future::ready(1).delay(Duration::from_millis(2000)); + /// dbg!(a.await); + /// # }) + /// ``` + #[cfg(feature = "unstable")] + #[cfg_attr(feature = "docs", doc(cfg(unstable)))] + fn delay(self, dur: Duration) -> DelayFuture + where + Self: Sized, + { + DelayFuture::new(self, dur) + } + + /// Flatten out the execution of this future when the result itself + /// can be converted into another future. + /// + /// # Examples + /// + /// ``` + /// # async_std::task::block_on(async { + /// use async_std::prelude::*; + /// + /// let nested_future = async { async { 1 } }; + /// let future = nested_future.flatten(); + /// assert_eq!(future.await, 1); + /// # }) + /// ``` + #[cfg(feature = "unstable")] + #[cfg_attr(feature = "docs", doc(cfg(unstable)))] + fn flatten( + self, + ) -> FlattenFuture::Future> + where + Self: Sized, + ::Output: IntoFuture, + { + FlattenFuture::new(self) + } + + #[doc = r#" + Waits for one of two similarly-typed futures to complete. + + Awaits multiple futures simultaneously, returning the output of the + first future that completes. + + This function will return a new future which awaits for either one of both + futures to complete. If multiple futures are completed at the same time, + resolution will occur in the order that they have been passed. + + Note that this function consumes all futures passed, and once a future is + completed, all other futures are dropped. + + # Examples + + ``` + # async_std::task::block_on(async { + use async_std::prelude::*; + use async_std::future; + + let a = future::pending(); + let b = future::ready(1u8); + let c = future::ready(2u8); + + let f = a.race(b).race(c); + assert_eq!(f.await, 1u8); + # }); + ``` + "#] + #[cfg(feature = "unstable")] + #[cfg_attr(feature = "docs", doc(cfg(unstable)))] + fn race( + self, + other: F, + ) -> Race + where + Self: std::future::Future + Sized, + F: std::future::Future::Output>, + { + Race::new(self, other) + } + + #[doc = r#" + Waits for one of two similarly-typed fallible futures to complete. + + Awaits multiple futures simultaneously, returning all results once complete. + + `try_race` is similar to [`race`], but keeps going if a future + resolved to an error until all futures have been resolved. In which case + an error is returned. + + The ordering of which value is yielded when two futures resolve + simultaneously is intentionally left unspecified. + + [`race`]: #method.race + + # Examples + + ``` + # fn main() -> std::io::Result<()> { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::future; + use std::io::{Error, ErrorKind}; + + let a = future::pending::>(); + let b = future::ready(Err(Error::from(ErrorKind::Other))); + let c = future::ready(Ok(1u8)); + + let f = a.try_race(b).try_race(c); + assert_eq!(f.await?, 1u8); + # + # Ok(()) }) } + ``` + "#] + #[cfg(feature = "unstable")] + #[cfg_attr(feature = "docs", doc(cfg(unstable)))] + fn try_race( + self, + other: F + ) -> TryRace + where + Self: std::future::Future> + Sized, + F: std::future::Future::Output>, + { + TryRace::new(self, other) + } + #[doc = r#" - Extension methods for [`Future`]. + Waits for two similarly-typed futures to complete. + + Awaits multiple futures simultaneously, returning the output of the + futures once both complete. + + This function returns a new future which polls both futures + concurrently. + + # Examples + + ``` + # async_std::task::block_on(async { + use async_std::prelude::*; + use async_std::future; + + let a = future::ready(1u8); + let b = future::ready(2u16); - [`Future`]: ../future/trait.Future.html + let f = a.join(b); + assert_eq!(f.await, (1u8, 2u16)); + # }); + ``` "#] - pub trait FutureExt: Future { - /// Returns a Future that delays execution for a specified time. - /// - /// # Examples - /// - /// ``` - /// # async_std::task::block_on(async { - /// use async_std::prelude::*; - /// use async_std::future; - /// use std::time::Duration; - /// - /// let a = future::ready(1).delay(Duration::from_millis(2000)); - /// dbg!(a.await); - /// # }) - /// ``` - #[cfg(feature = "unstable")] - #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - fn delay(self, dur: Duration) -> DelayFuture - where - Self: Sized, - { - DelayFuture::new(self, dur) - } - - /// Flatten out the execution of this future when the result itself - /// can be converted into another future. - /// - /// # Examples - /// - /// ``` - /// # async_std::task::block_on(async { - /// use async_std::prelude::*; - /// - /// let nested_future = async { async { 1 } }; - /// let future = nested_future.flatten(); - /// assert_eq!(future.await, 1); - /// # }) - /// ``` - #[cfg(feature = "unstable")] - #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - fn flatten( - self, - ) -> FlattenFuture::Future> - where - Self: Sized, - ::Output: IntoFuture, - { - FlattenFuture::new(self) - } - - #[doc = r#" - Waits for one of two similarly-typed futures to complete. - - Awaits multiple futures simultaneously, returning the output of the - first future that completes. - - This function will return a new future which awaits for either one of both - futures to complete. If multiple futures are completed at the same time, - resolution will occur in the order that they have been passed. - - Note that this function consumes all futures passed, and once a future is - completed, all other futures are dropped. - - # Examples - - ``` - # async_std::task::block_on(async { - use async_std::prelude::*; - use async_std::future; - - let a = future::pending(); - let b = future::ready(1u8); - let c = future::ready(2u8); - - let f = a.race(b).race(c); - assert_eq!(f.await, 1u8); - # }); - ``` - "#] - #[cfg(feature = "unstable")] - #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - fn race( - self, - other: F, - ) -> Race - where - Self: std::future::Future + Sized, - F: std::future::Future::Output>, - { - Race::new(self, other) - } - - #[doc = r#" - Waits for one of two similarly-typed fallible futures to complete. - - Awaits multiple futures simultaneously, returning all results once complete. - - `try_race` is similar to [`race`], but keeps going if a future - resolved to an error until all futures have been resolved. In which case - an error is returned. - - The ordering of which value is yielded when two futures resolve - simultaneously is intentionally left unspecified. - - [`race`]: #method.race - - # Examples - - ``` - # fn main() -> std::io::Result<()> { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::future; - use std::io::{Error, ErrorKind}; - - let a = future::pending::>(); - let b = future::ready(Err(Error::from(ErrorKind::Other))); - let c = future::ready(Ok(1u8)); - - let f = a.try_race(b).try_race(c); - assert_eq!(f.await?, 1u8); - # - # Ok(()) }) } - ``` - "#] - #[cfg(feature = "unstable")] - #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - fn try_race( - self, - other: F - ) -> TryRace - where - Self: std::future::Future> + Sized, - F: std::future::Future::Output>, - { - TryRace::new(self, other) - } - - #[doc = r#" - Waits for two similarly-typed futures to complete. - - Awaits multiple futures simultaneously, returning the output of the - futures once both complete. - - This function returns a new future which polls both futures - concurrently. - - # Examples - - ``` - # async_std::task::block_on(async { - use async_std::prelude::*; - use async_std::future; - - let a = future::ready(1u8); - let b = future::ready(2u16); - - let f = a.join(b); - assert_eq!(f.await, (1u8, 2u16)); - # }); - ``` - "#] - #[cfg(any(feature = "unstable", feature = "docs"))] - #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - fn join( - self, - other: F - ) -> Join - where - Self: std::future::Future + Sized, - F: std::future::Future, - { - Join::new(self, other) - } - - #[doc = r#" - Waits for two similarly-typed fallible futures to complete. - - Awaits multiple futures simultaneously, returning all results once - complete. - - `try_join` is similar to [`join`], but returns an error immediately - if a future resolves to an error. - - [`join`]: #method.join - - # Examples - - ``` - # fn main() -> std::io::Result<()> { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::future; - - let a = future::ready(Err::("Error")); - let b = future::ready(Ok(1u8)); - - let f = a.try_join(b); - assert_eq!(f.await, Err("Error")); - - let a = future::ready(Ok::(1u8)); - let b = future::ready(Ok::(2u16)); - - let f = a.try_join(b); - assert_eq!(f.await, Ok((1u8, 2u16))); - # - # Ok(()) }) } - ``` - "#] - #[cfg(any(feature = "unstable", feature = "docs"))] - #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - fn try_join( - self, - other: F - ) -> TryJoin - where - Self: std::future::Future> + Sized, - F: std::future::Future>, - { - TryJoin::new(self, other) - } - - #[doc = r#" - Waits for both the future and a timeout, if the timeout completes before - the future, it returns a TimeoutError. - - # Example - ``` - # async_std::task::block_on(async { - # - use std::time::Duration; - - use async_std::prelude::*; - use async_std::future; - - let fut = future::ready(0); - let dur = Duration::from_millis(100); - let res = fut.timeout(dur).await; - assert!(res.is_ok()); - - let fut = future::pending::<()>(); - let dur = Duration::from_millis(100); - let res = fut.timeout(dur).await; - assert!(res.is_err()) - # - # }); - ``` - "#] - #[cfg(any(all(feature = "default", feature = "unstable"), feature = "docs"))] - #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - fn timeout(self, dur: Duration) -> TimeoutFuture - where Self: Sized - { - TimeoutFuture::new(self, dur) - } + #[cfg(any(feature = "unstable", feature = "docs"))] + #[cfg_attr(feature = "docs", doc(cfg(unstable)))] + fn join( + self, + other: F + ) -> Join + where + Self: std::future::Future + Sized, + F: std::future::Future, + { + Join::new(self, other) } + #[doc = r#" + Waits for two similarly-typed fallible futures to complete. + + Awaits multiple futures simultaneously, returning all results once + complete. + + `try_join` is similar to [`join`], but returns an error immediately + if a future resolves to an error. + + [`join`]: #method.join + + # Examples + + ``` + # fn main() -> std::io::Result<()> { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::future; + + let a = future::ready(Err::("Error")); + let b = future::ready(Ok(1u8)); + + let f = a.try_join(b); + assert_eq!(f.await, Err("Error")); + + let a = future::ready(Ok::(1u8)); + let b = future::ready(Ok::(2u16)); + + let f = a.try_join(b); + assert_eq!(f.await, Ok((1u8, 2u16))); + # + # Ok(()) }) } + ``` + "#] + #[cfg(any(feature = "unstable", feature = "docs"))] + #[cfg_attr(feature = "docs", doc(cfg(unstable)))] + fn try_join( + self, + other: F + ) -> TryJoin + where + Self: std::future::Future> + Sized, + F: std::future::Future>, + { + TryJoin::new(self, other) + } + + #[doc = r#" + Waits for both the future and a timeout, if the timeout completes before + the future, it returns a TimeoutError. + + # Example + ``` + # async_std::task::block_on(async { + # + use std::time::Duration; + + use async_std::prelude::*; + use async_std::future; + + let fut = future::ready(0); + let dur = Duration::from_millis(100); + let res = fut.timeout(dur).await; + assert!(res.is_ok()); + + let fut = future::pending::<()>(); + let dur = Duration::from_millis(100); + let res = fut.timeout(dur).await; + assert!(res.is_err()) + # + # }); + ``` + "#] + #[cfg(any(all(feature = "default", feature = "unstable"), feature = "docs"))] + #[cfg_attr(feature = "docs", doc(cfg(unstable)))] + fn timeout(self, dur: Duration) -> TimeoutFuture + where Self: Sized + { + TimeoutFuture::new(self, dur) + } +} + impl FutureExt for T {} diff --git a/src/io/buf_read/mod.rs b/src/io/buf_read/mod.rs index f8bffaf3..75247a51 100644 --- a/src/io/buf_read/mod.rs +++ b/src/io/buf_read/mod.rs @@ -17,225 +17,225 @@ use crate::task::{Context, Poll}; pub use futures_io::AsyncBufRead as BufRead; - #[doc = r#" - Extension methods for [`BufRead`]. +#[doc = r#" + Extension methods for [`BufRead`]. - [`BufRead`]: ../trait.BufRead.html + [`BufRead`]: ../trait.BufRead.html +"#] +pub trait BufReadExt: BufRead { + #[doc = r#" + Reads all bytes into `buf` until the delimiter `byte` or EOF is reached. + + This function will read bytes from the underlying stream until the delimiter or EOF + is found. Once found, all bytes up to, and including, the delimiter (if found) will + be appended to `buf`. + + If successful, this function will return the total number of bytes read. + + # Examples + + ```no_run + # fn main() -> std::io::Result<()> { async_std::task::block_on(async { + # + use async_std::fs::File; + use async_std::io::BufReader; + use async_std::prelude::*; + + let mut file = BufReader::new(File::open("a.txt").await?); + + let mut buf = Vec::with_capacity(1024); + let n = file.read_until(b'\n', &mut buf).await?; + # + # Ok(()) }) } + ``` + + Multiple successful calls to `read_until` append all bytes up to and including to + `buf`: + ``` + # fn main() -> std::io::Result<()> { async_std::task::block_on(async { + # + use async_std::io::BufReader; + use async_std::prelude::*; + + let from: &[u8] = b"append\nexample\n"; + let mut reader = BufReader::new(from); + let mut buf = vec![]; + + let mut size = reader.read_until(b'\n', &mut buf).await?; + assert_eq!(size, 7); + assert_eq!(buf, b"append\n"); + + size += reader.read_until(b'\n', &mut buf).await?; + assert_eq!(size, from.len()); + + assert_eq!(buf, from); + # + # Ok(()) }) } + ``` "#] - pub trait BufReadExt: BufRead { - #[doc = r#" - Reads all bytes into `buf` until the delimiter `byte` or EOF is reached. - - This function will read bytes from the underlying stream until the delimiter or EOF - is found. Once found, all bytes up to, and including, the delimiter (if found) will - be appended to `buf`. - - If successful, this function will return the total number of bytes read. - - # Examples - - ```no_run - # fn main() -> std::io::Result<()> { async_std::task::block_on(async { - # - use async_std::fs::File; - use async_std::io::BufReader; - use async_std::prelude::*; - - let mut file = BufReader::new(File::open("a.txt").await?); - - let mut buf = Vec::with_capacity(1024); - let n = file.read_until(b'\n', &mut buf).await?; - # - # Ok(()) }) } - ``` - - Multiple successful calls to `read_until` append all bytes up to and including to - `buf`: - ``` - # fn main() -> std::io::Result<()> { async_std::task::block_on(async { - # - use async_std::io::BufReader; - use async_std::prelude::*; - - let from: &[u8] = b"append\nexample\n"; - let mut reader = BufReader::new(from); - let mut buf = vec![]; - - let mut size = reader.read_until(b'\n', &mut buf).await?; - assert_eq!(size, 7); - assert_eq!(buf, b"append\n"); - - size += reader.read_until(b'\n', &mut buf).await?; - assert_eq!(size, from.len()); - - assert_eq!(buf, from); - # - # Ok(()) }) } - ``` - "#] - fn read_until<'a>( - &'a mut self, - byte: u8, - buf: &'a mut Vec, - ) -> ReadUntilFuture<'a, Self> - where - Self: Unpin, - { - ReadUntilFuture { - reader: self, - byte, - buf, - read: 0, - } + fn read_until<'a>( + &'a mut self, + byte: u8, + buf: &'a mut Vec, + ) -> ReadUntilFuture<'a, Self> + where + Self: Unpin, + { + ReadUntilFuture { + reader: self, + byte, + buf, + read: 0, } + } - #[doc = r#" - Reads all bytes and appends them into `buf` until a newline (the 0xA byte) is - reached. - - This function will read bytes from the underlying stream until the newline - delimiter (the 0xA byte) or EOF is found. Once found, all bytes up to, and - including, the delimiter (if found) will be appended to `buf`. - - If successful, this function will return the total number of bytes read. - - If this function returns `Ok(0)`, the stream has reached EOF. - - # Errors - - This function has the same error semantics as [`read_until`] and will also return - an error if the read bytes are not valid UTF-8. If an I/O error is encountered then - `buf` may contain some bytes already read in the event that all data read so far - was valid UTF-8. - - [`read_until`]: #method.read_until - - # Examples - - ```no_run - # fn main() -> std::io::Result<()> { async_std::task::block_on(async { - # - use async_std::fs::File; - use async_std::io::BufReader; - use async_std::prelude::*; - - let mut file = BufReader::new(File::open("a.txt").await?); - - let mut buf = String::new(); - file.read_line(&mut buf).await?; - # - # Ok(()) }) } - ``` - "#] - fn read_line<'a>( - &'a mut self, - buf: &'a mut String, - ) -> ReadLineFuture<'a, Self> - where - Self: Unpin, - { - ReadLineFuture { - reader: self, - bytes: unsafe { mem::replace(buf.as_mut_vec(), Vec::new()) }, - buf, - read: 0, - } + #[doc = r#" + Reads all bytes and appends them into `buf` until a newline (the 0xA byte) is + reached. + + This function will read bytes from the underlying stream until the newline + delimiter (the 0xA byte) or EOF is found. Once found, all bytes up to, and + including, the delimiter (if found) will be appended to `buf`. + + If successful, this function will return the total number of bytes read. + + If this function returns `Ok(0)`, the stream has reached EOF. + + # Errors + + This function has the same error semantics as [`read_until`] and will also return + an error if the read bytes are not valid UTF-8. If an I/O error is encountered then + `buf` may contain some bytes already read in the event that all data read so far + was valid UTF-8. + + [`read_until`]: #method.read_until + + # Examples + + ```no_run + # fn main() -> std::io::Result<()> { async_std::task::block_on(async { + # + use async_std::fs::File; + use async_std::io::BufReader; + use async_std::prelude::*; + + let mut file = BufReader::new(File::open("a.txt").await?); + + let mut buf = String::new(); + file.read_line(&mut buf).await?; + # + # Ok(()) }) } + ``` + "#] + fn read_line<'a>( + &'a mut self, + buf: &'a mut String, + ) -> ReadLineFuture<'a, Self> + where + Self: Unpin, + { + ReadLineFuture { + reader: self, + bytes: unsafe { mem::replace(buf.as_mut_vec(), Vec::new()) }, + buf, + read: 0, } + } - #[doc = r#" - Returns a stream over the lines of this byte stream. + #[doc = r#" + Returns a stream over the lines of this byte stream. - The stream returned from this function will yield instances of - [`io::Result`]`<`[`String`]`>`. Each string returned will *not* have a newline byte - (the 0xA byte) or CRLF (0xD, 0xA bytes) at the end. + The stream returned from this function will yield instances of + [`io::Result`]`<`[`String`]`>`. Each string returned will *not* have a newline byte + (the 0xA byte) or CRLF (0xD, 0xA bytes) at the end. - [`io::Result`]: type.Result.html - [`String`]: https://doc.rust-lang.org/std/string/struct.String.html + [`io::Result`]: type.Result.html + [`String`]: https://doc.rust-lang.org/std/string/struct.String.html - # Examples + # Examples - ```no_run - # fn main() -> std::io::Result<()> { async_std::task::block_on(async { - # - use async_std::fs::File; - use async_std::io::BufReader; - use async_std::prelude::*; + ```no_run + # fn main() -> std::io::Result<()> { async_std::task::block_on(async { + # + use async_std::fs::File; + use async_std::io::BufReader; + use async_std::prelude::*; - let file = File::open("a.txt").await?; - let mut lines = BufReader::new(file).lines(); - let mut count = 0; + let file = File::open("a.txt").await?; + let mut lines = BufReader::new(file).lines(); + let mut count = 0; - while let Some(line) = lines.next().await { - line?; - count += 1; - } - # - # Ok(()) }) } - ``` - "#] - fn lines(self) -> Lines - where - Self: Unpin + Sized, - { - Lines { - reader: self, - buf: String::new(), - bytes: Vec::new(), - read: 0, - } + while let Some(line) = lines.next().await { + line?; + count += 1; } + # + # Ok(()) }) } + ``` + "#] + fn lines(self) -> Lines + where + Self: Unpin + Sized, + { + Lines { + reader: self, + buf: String::new(), + bytes: Vec::new(), + read: 0, + } + } - #[doc = r#" - Returns a stream over the contents of this reader split on the byte `byte`. - - The stream returned from this function will return instances of - [`io::Result`]`<`[`Vec`]`>`. Each vector returned will *not* have - the delimiter byte at the end. - - This function will yield errors whenever [`read_until`] would have - also yielded an error. - - [`io::Result`]: type.Result.html - [`Vec`]: ../vec/struct.Vec.html - [`read_until`]: #method.read_until - - # Examples - - [`std::io::Cursor`][`Cursor`] is a type that implements `BufRead`. In - this example, we use [`Cursor`] to iterate over all hyphen delimited - segments in a byte slice - - [`Cursor`]: struct.Cursor.html - - ``` - # fn main() -> std::io::Result<()> { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::io; - - let cursor = io::Cursor::new(b"lorem-ipsum-dolor"); - - let mut split_iter = cursor.split(b'-').map(|l| l.unwrap()); - assert_eq!(split_iter.next().await, Some(b"lorem".to_vec())); - assert_eq!(split_iter.next().await, Some(b"ipsum".to_vec())); - assert_eq!(split_iter.next().await, Some(b"dolor".to_vec())); - assert_eq!(split_iter.next().await, None); - # - # Ok(()) }) } - ``` - "#] - fn split(self, byte: u8) -> Split - where - Self: Sized, - { - Split { - reader: self, - buf: Vec::new(), - delim: byte, - read: 0, - } + #[doc = r#" + Returns a stream over the contents of this reader split on the byte `byte`. + + The stream returned from this function will return instances of + [`io::Result`]`<`[`Vec`]`>`. Each vector returned will *not* have + the delimiter byte at the end. + + This function will yield errors whenever [`read_until`] would have + also yielded an error. + + [`io::Result`]: type.Result.html + [`Vec`]: ../vec/struct.Vec.html + [`read_until`]: #method.read_until + + # Examples + + [`std::io::Cursor`][`Cursor`] is a type that implements `BufRead`. In + this example, we use [`Cursor`] to iterate over all hyphen delimited + segments in a byte slice + + [`Cursor`]: struct.Cursor.html + + ``` + # fn main() -> std::io::Result<()> { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::io; + + let cursor = io::Cursor::new(b"lorem-ipsum-dolor"); + + let mut split_iter = cursor.split(b'-').map(|l| l.unwrap()); + assert_eq!(split_iter.next().await, Some(b"lorem".to_vec())); + assert_eq!(split_iter.next().await, Some(b"ipsum".to_vec())); + assert_eq!(split_iter.next().await, Some(b"dolor".to_vec())); + assert_eq!(split_iter.next().await, None); + # + # Ok(()) }) } + ``` + "#] + fn split(self, byte: u8) -> Split + where + Self: Sized, + { + Split { + reader: self, + buf: Vec::new(), + delim: byte, + read: 0, } } +} impl BufReadExt for T {} diff --git a/src/io/read/mod.rs b/src/io/read/mod.rs index 0109a3ac..40542258 100644 --- a/src/io/read/mod.rs +++ b/src/io/read/mod.rs @@ -23,355 +23,355 @@ pub use take::Take; pub use futures_io::AsyncRead as Read; +#[doc = r#" + Extension methods for [`Read`]. + + [`Read`]: ../trait.Read.html +"#] +pub trait ReadExt: Read { #[doc = r#" - Extension methods for [`Read`]. + Reads some bytes from the byte stream. + + Returns the number of bytes read from the start of the buffer. + + If the return value is `Ok(n)`, then it must be guaranteed that + `0 <= n <= buf.len()`. A nonzero `n` value indicates that the buffer has been + filled in with `n` bytes of data. If `n` is `0`, then it can indicate one of two + scenarios: + + 1. This reader has reached its "end of file" and will likely no longer be able to + produce bytes. Note that this does not mean that the reader will always no + longer be able to produce bytes. + 2. The buffer specified was 0 bytes in length. - [`Read`]: ../trait.Read.html + # Examples + + ```no_run + # fn main() -> std::io::Result<()> { async_std::task::block_on(async { + # + use async_std::fs::File; + use async_std::prelude::*; + + let mut file = File::open("a.txt").await?; + + let mut buf = vec![0; 1024]; + let n = file.read(&mut buf).await?; + # + # Ok(()) }) } + ``` "#] - pub trait ReadExt: Read { - #[doc = r#" - Reads some bytes from the byte stream. - - Returns the number of bytes read from the start of the buffer. - - If the return value is `Ok(n)`, then it must be guaranteed that - `0 <= n <= buf.len()`. A nonzero `n` value indicates that the buffer has been - filled in with `n` bytes of data. If `n` is `0`, then it can indicate one of two - scenarios: - - 1. This reader has reached its "end of file" and will likely no longer be able to - produce bytes. Note that this does not mean that the reader will always no - longer be able to produce bytes. - 2. The buffer specified was 0 bytes in length. - - # Examples - - ```no_run - # fn main() -> std::io::Result<()> { async_std::task::block_on(async { - # - use async_std::fs::File; - use async_std::prelude::*; - - let mut file = File::open("a.txt").await?; - - let mut buf = vec![0; 1024]; - let n = file.read(&mut buf).await?; - # - # Ok(()) }) } - ``` - "#] - fn read<'a>( - &'a mut self, - buf: &'a mut [u8], - ) -> ReadFuture<'a, Self> - where - Self: Unpin - { - ReadFuture { reader: self, buf } - } + fn read<'a>( + &'a mut self, + buf: &'a mut [u8], + ) -> ReadFuture<'a, Self> + where + Self: Unpin + { + ReadFuture { reader: self, buf } + } - #[doc = r#" - Like [`read`], except that it reads into a slice of buffers. + #[doc = r#" + Like [`read`], except that it reads into a slice of buffers. - Data is copied to fill each buffer in order, with the final buffer written to - possibly being only partially filled. This method must behave as a single call to - [`read`] with the buffers concatenated would. + Data is copied to fill each buffer in order, with the final buffer written to + possibly being only partially filled. This method must behave as a single call to + [`read`] with the buffers concatenated would. - The default implementation calls [`read`] with either the first nonempty buffer - provided, or an empty one if none exists. + The default implementation calls [`read`] with either the first nonempty buffer + provided, or an empty one if none exists. - [`read`]: #tymethod.read - "#] - fn read_vectored<'a>( - &'a mut self, - bufs: &'a mut [IoSliceMut<'a>], - ) -> ReadVectoredFuture<'a, Self> - where - Self: Unpin, - { - ReadVectoredFuture { reader: self, bufs } - } + [`read`]: #tymethod.read + "#] + fn read_vectored<'a>( + &'a mut self, + bufs: &'a mut [IoSliceMut<'a>], + ) -> ReadVectoredFuture<'a, Self> + where + Self: Unpin, + { + ReadVectoredFuture { reader: self, bufs } + } - #[doc = r#" - Reads all bytes from the byte stream. + #[doc = r#" + Reads all bytes from the byte stream. - All bytes read from this stream will be appended to the specified buffer `buf`. - This function will continuously call [`read`] to append more data to `buf` until - [`read`] returns either `Ok(0)` or an error. + All bytes read from this stream will be appended to the specified buffer `buf`. + This function will continuously call [`read`] to append more data to `buf` until + [`read`] returns either `Ok(0)` or an error. - If successful, this function will return the total number of bytes read. + If successful, this function will return the total number of bytes read. - [`read`]: #tymethod.read + [`read`]: #tymethod.read - # Examples + # Examples - ```no_run - # fn main() -> std::io::Result<()> { async_std::task::block_on(async { - # - use async_std::fs::File; - use async_std::prelude::*; + ```no_run + # fn main() -> std::io::Result<()> { async_std::task::block_on(async { + # + use async_std::fs::File; + use async_std::prelude::*; - let mut file = File::open("a.txt").await?; + let mut file = File::open("a.txt").await?; - let mut buf = Vec::new(); - file.read_to_end(&mut buf).await?; - # - # Ok(()) }) } - ``` - "#] - fn read_to_end<'a>( - &'a mut self, - buf: &'a mut Vec, - ) -> ReadToEndFuture<'a, Self> - where - Self: Unpin, - { - let start_len = buf.len(); - ReadToEndFuture { - reader: self, - buf, - start_len, - } + let mut buf = Vec::new(); + file.read_to_end(&mut buf).await?; + # + # Ok(()) }) } + ``` + "#] + fn read_to_end<'a>( + &'a mut self, + buf: &'a mut Vec, + ) -> ReadToEndFuture<'a, Self> + where + Self: Unpin, + { + let start_len = buf.len(); + ReadToEndFuture { + reader: self, + buf, + start_len, } + } - #[doc = r#" - Reads all bytes from the byte stream and appends them into a string. + #[doc = r#" + Reads all bytes from the byte stream and appends them into a string. - If successful, this function will return the number of bytes read. + If successful, this function will return the number of bytes read. - If the data in this stream is not valid UTF-8 then an error will be returned and - `buf` will be left unmodified. + If the data in this stream is not valid UTF-8 then an error will be returned and + `buf` will be left unmodified. - # Examples + # Examples - ```no_run - # fn main() -> std::io::Result<()> { async_std::task::block_on(async { - # - use async_std::fs::File; - use async_std::prelude::*; + ```no_run + # fn main() -> std::io::Result<()> { async_std::task::block_on(async { + # + use async_std::fs::File; + use async_std::prelude::*; - let mut file = File::open("a.txt").await?; + let mut file = File::open("a.txt").await?; - let mut buf = String::new(); - file.read_to_string(&mut buf).await?; - # - # Ok(()) }) } - ``` - "#] - fn read_to_string<'a>( - &'a mut self, - buf: &'a mut String, - ) -> ReadToStringFuture<'a, Self> - where - Self: Unpin, - { - let start_len = buf.len(); - ReadToStringFuture { - reader: self, - bytes: unsafe { mem::replace(buf.as_mut_vec(), Vec::new()) }, - buf, - start_len, - } + let mut buf = String::new(); + file.read_to_string(&mut buf).await?; + # + # Ok(()) }) } + ``` + "#] + fn read_to_string<'a>( + &'a mut self, + buf: &'a mut String, + ) -> ReadToStringFuture<'a, Self> + where + Self: Unpin, + { + let start_len = buf.len(); + ReadToStringFuture { + reader: self, + bytes: unsafe { mem::replace(buf.as_mut_vec(), Vec::new()) }, + buf, + start_len, } + } - #[doc = r#" - Reads the exact number of bytes required to fill `buf`. + #[doc = r#" + Reads the exact number of bytes required to fill `buf`. - This function reads as many bytes as necessary to completely fill the specified - buffer `buf`. + This function reads as many bytes as necessary to completely fill the specified + buffer `buf`. - No guarantees are provided about the contents of `buf` when this function is - called, implementations cannot rely on any property of the contents of `buf` being - true. It is recommended that implementations only write data to `buf` instead of - reading its contents. + No guarantees are provided about the contents of `buf` when this function is + called, implementations cannot rely on any property of the contents of `buf` being + true. It is recommended that implementations only write data to `buf` instead of + reading its contents. - If this function encounters an "end of file" before completely filling the buffer, - it returns an error of the kind [`ErrorKind::UnexpectedEof`]. The contents of - `buf` are unspecified in this case. + If this function encounters an "end of file" before completely filling the buffer, + it returns an error of the kind [`ErrorKind::UnexpectedEof`]. The contents of + `buf` are unspecified in this case. - If any other read error is encountered then this function immediately returns. The - contents of `buf` are unspecified in this case. + If any other read error is encountered then this function immediately returns. The + contents of `buf` are unspecified in this case. - If this function returns an error, it is unspecified how many bytes it has read, - but it will never read more than would be necessary to completely fill the buffer. + If this function returns an error, it is unspecified how many bytes it has read, + but it will never read more than would be necessary to completely fill the buffer. - [`ErrorKind::UnexpectedEof`]: enum.ErrorKind.html#variant.UnexpectedEof + [`ErrorKind::UnexpectedEof`]: enum.ErrorKind.html#variant.UnexpectedEof - # Examples + # Examples - ```no_run - # fn main() -> std::io::Result<()> { async_std::task::block_on(async { - # - use async_std::fs::File; - use async_std::prelude::*; + ```no_run + # fn main() -> std::io::Result<()> { async_std::task::block_on(async { + # + use async_std::fs::File; + use async_std::prelude::*; - let mut file = File::open("a.txt").await?; + let mut file = File::open("a.txt").await?; - let mut buf = vec![0; 10]; - file.read_exact(&mut buf).await?; - # - # Ok(()) }) } - ``` - "#] - fn read_exact<'a>( - &'a mut self, - buf: &'a mut [u8], - ) -> ReadExactFuture<'a, Self> - where - Self: Unpin, - { - ReadExactFuture { reader: self, buf } - } + let mut buf = vec![0; 10]; + file.read_exact(&mut buf).await?; + # + # Ok(()) }) } + ``` + "#] + fn read_exact<'a>( + &'a mut self, + buf: &'a mut [u8], + ) -> ReadExactFuture<'a, Self> + where + Self: Unpin, + { + ReadExactFuture { reader: self, buf } + } - #[doc = r#" - Creates an adaptor which will read at most `limit` bytes from it. + #[doc = r#" + Creates an adaptor which will read at most `limit` bytes from it. - This function returns a new instance of `Read` which will read at most - `limit` bytes, after which it will always return EOF ([`Ok(0)`]). Any - read errors will not count towards the number of bytes read and future - calls to [`read`] may succeed. + This function returns a new instance of `Read` which will read at most + `limit` bytes, after which it will always return EOF ([`Ok(0)`]). Any + read errors will not count towards the number of bytes read and future + calls to [`read`] may succeed. - # Examples + # Examples - [`File`]s implement `Read`: + [`File`]s implement `Read`: - [`File`]: ../fs/struct.File.html - [`Ok(0)`]: ../../std/result/enum.Result.html#variant.Ok - [`read`]: tymethod.read + [`File`]: ../fs/struct.File.html + [`Ok(0)`]: ../../std/result/enum.Result.html#variant.Ok + [`read`]: tymethod.read - ```no_run - # fn main() -> std::io::Result<()> { async_std::task::block_on(async { - # - use async_std::io::prelude::*; - use async_std::fs::File; + ```no_run + # fn main() -> std::io::Result<()> { async_std::task::block_on(async { + # + use async_std::io::prelude::*; + use async_std::fs::File; - let f = File::open("foo.txt").await?; - let mut buffer = [0; 5]; + let f = File::open("foo.txt").await?; + let mut buffer = [0; 5]; - // read at most five bytes - let mut handle = f.take(5); + // read at most five bytes + let mut handle = f.take(5); + + handle.read(&mut buffer).await?; + # + # Ok(()) }) } + ``` + "#] + fn take(self, limit: u64) -> Take + where + Self: Sized, + { + Take { inner: self, limit } + } + + #[doc = r#" + Creates a "by reference" adaptor for this instance of `Read`. + + The returned adaptor also implements `Read` and will simply borrow this + current reader. + + # Examples + + [`File`][file]s implement `Read`: + + [file]: ../fs/struct.File.html + + ```no_run + # fn main() -> std::io::Result<()> { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::fs::File; + + let mut f = File::open("foo.txt").await?; + let mut buffer = Vec::new(); + let mut other_buffer = Vec::new(); - handle.read(&mut buffer).await?; - # - # Ok(()) }) } - ``` - "#] - fn take(self, limit: u64) -> Take - where - Self: Sized, { - Take { inner: self, limit } - } + let reference = f.by_ref(); + + // read at most 5 bytes + reference.take(5).read_to_end(&mut buffer).await?; - #[doc = r#" - Creates a "by reference" adaptor for this instance of `Read`. + } // drop our &mut reference so we can use f again - The returned adaptor also implements `Read` and will simply borrow this - current reader. + // original file still usable, read the rest + f.read_to_end(&mut other_buffer).await?; + # + # Ok(()) }) } + ``` + "#] + fn by_ref(&mut self) -> &mut Self where Self: Sized { self } - # Examples - [`File`][file]s implement `Read`: + #[doc = r#" + Transforms this `Read` instance to a `Stream` over its bytes. - [file]: ../fs/struct.File.html + The returned type implements `Stream` where the `Item` is + `Result`. + The yielded item is `Ok` if a byte was successfully read and `Err` + otherwise. EOF is mapped to returning `None` from this iterator. - ```no_run - # fn main() -> std::io::Result<()> { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::fs::File; + # Examples - let mut f = File::open("foo.txt").await?; - let mut buffer = Vec::new(); - let mut other_buffer = Vec::new(); + [`File`][file]s implement `Read`: - { - let reference = f.by_ref(); + [file]: ../fs/struct.File.html - // read at most 5 bytes - reference.take(5).read_to_end(&mut buffer).await?; + ```no_run + # fn main() -> std::io::Result<()> { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::fs::File; - } // drop our &mut reference so we can use f again + let f = File::open("foo.txt").await?; + let mut s = f.bytes(); - // original file still usable, read the rest - f.read_to_end(&mut other_buffer).await?; - # - # Ok(()) }) } - ``` - "#] - fn by_ref(&mut self) -> &mut Self where Self: Sized { self } - - - #[doc = r#" - Transforms this `Read` instance to a `Stream` over its bytes. - - The returned type implements `Stream` where the `Item` is - `Result`. - The yielded item is `Ok` if a byte was successfully read and `Err` - otherwise. EOF is mapped to returning `None` from this iterator. - - # Examples - - [`File`][file]s implement `Read`: - - [file]: ../fs/struct.File.html - - ```no_run - # fn main() -> std::io::Result<()> { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::fs::File; - - let f = File::open("foo.txt").await?; - let mut s = f.bytes(); - - while let Some(byte) = s.next().await { - println!("{}", byte.unwrap()); - } - # - # Ok(()) }) } - ``` - "#] - fn bytes(self) -> Bytes where Self: Sized { - Bytes { inner: self } + while let Some(byte) = s.next().await { + println!("{}", byte.unwrap()); } + # + # Ok(()) }) } + ``` + "#] + fn bytes(self) -> Bytes where Self: Sized { + Bytes { inner: self } + } - #[doc = r#" - Creates an adaptor which will chain this stream with another. + #[doc = r#" + Creates an adaptor which will chain this stream with another. - The returned `Read` instance will first read all bytes from this object - until EOF is encountered. Afterwards the output is equivalent to the - output of `next`. + The returned `Read` instance will first read all bytes from this object + until EOF is encountered. Afterwards the output is equivalent to the + output of `next`. - # Examples + # Examples - [`File`][file]s implement `Read`: + [`File`][file]s implement `Read`: - [file]: ../fs/struct.File.html + [file]: ../fs/struct.File.html - ```no_run - # fn main() -> std::io::Result<()> { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::fs::File; + ```no_run + # fn main() -> std::io::Result<()> { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::fs::File; - let f1 = File::open("foo.txt").await?; - let f2 = File::open("bar.txt").await?; + let f1 = File::open("foo.txt").await?; + let f2 = File::open("bar.txt").await?; - let mut handle = f1.chain(f2); - let mut buffer = String::new(); + let mut handle = f1.chain(f2); + let mut buffer = String::new(); - // read the value into a String. We could use any Read method here, - // this is just one example. - handle.read_to_string(&mut buffer).await?; - # - # Ok(()) }) } - ``` - "#] - fn chain(self, next: R) -> Chain where Self: Sized { - Chain { first: self, second: next, done_first: false } - } + // read the value into a String. We could use any Read method here, + // this is just one example. + handle.read_to_string(&mut buffer).await?; + # + # Ok(()) }) } + ``` + "#] + fn chain(self, next: R) -> Chain where Self: Sized { + Chain { first: self, second: next, done_first: false } } +} impl ReadExt for T {} diff --git a/src/io/seek/mod.rs b/src/io/seek/mod.rs index f2b60932..cb0b9e13 100644 --- a/src/io/seek/mod.rs +++ b/src/io/seek/mod.rs @@ -6,45 +6,45 @@ use crate::io::SeekFrom; pub use futures_io::AsyncSeek as Seek; +#[doc = r#" + Extension methods for [`Seek`]. + + [`Seek`]: ../trait.Seek.html +"#] +pub trait SeekExt: Seek { #[doc = r#" - Extension methods for [`Seek`]. + Seeks to a new position in a byte stream. + + Returns the new position in the byte stream. + + A seek beyond the end of stream is allowed, but behavior is defined by the + implementation. + + # Examples + + ```no_run + # fn main() -> std::io::Result<()> { async_std::task::block_on(async { + # + use async_std::fs::File; + use async_std::io::SeekFrom; + use async_std::prelude::*; + + let mut file = File::open("a.txt").await?; - [`Seek`]: ../trait.Seek.html + let file_len = file.seek(SeekFrom::End(0)).await?; + # + # Ok(()) }) } + ``` "#] - pub trait SeekExt: Seek { - #[doc = r#" - Seeks to a new position in a byte stream. - - Returns the new position in the byte stream. - - A seek beyond the end of stream is allowed, but behavior is defined by the - implementation. - - # Examples - - ```no_run - # fn main() -> std::io::Result<()> { async_std::task::block_on(async { - # - use async_std::fs::File; - use async_std::io::SeekFrom; - use async_std::prelude::*; - - let mut file = File::open("a.txt").await?; - - let file_len = file.seek(SeekFrom::End(0)).await?; - # - # Ok(()) }) } - ``` - "#] - fn seek( - &mut self, - pos: SeekFrom, - ) -> SeekFuture<'_, Self> - where - Self: Unpin, - { - SeekFuture { seeker: self, pos } - } + fn seek( + &mut self, + pos: SeekFrom, + ) -> SeekFuture<'_, Self> + where + Self: Unpin, + { + SeekFuture { seeker: self, pos } } +} impl SeekExt for T {} diff --git a/src/io/write/mod.rs b/src/io/write/mod.rs index d73c40d8..753e7e6a 100644 --- a/src/io/write/mod.rs +++ b/src/io/write/mod.rs @@ -14,174 +14,174 @@ use crate::io::{self, IoSlice}; pub use futures_io::AsyncWrite as Write; +#[doc = r#" + Extension methods for [`Write`]. + + [`Write`]: ../trait.Write.html +"#] +pub trait WriteExt: Write { + #[doc = r#" + Writes some bytes into the byte stream. + + Returns the number of bytes written from the start of the buffer. + + If the return value is `Ok(n)` then it must be guaranteed that + `0 <= n <= buf.len()`. A return value of `0` typically means that the underlying + object is no longer able to accept bytes and will likely not be able to in the + future as well, or that the buffer provided is empty. + + # Examples + + ```no_run + # fn main() -> std::io::Result<()> { async_std::task::block_on(async { + # + use async_std::fs::File; + use async_std::prelude::*; + + let mut file = File::create("a.txt").await?; + + let n = file.write(b"hello world").await?; + # + # Ok(()) }) } + ``` + "#] + fn write<'a>( + &'a mut self, + buf: &'a [u8], + ) -> WriteFuture<'a, Self> + where + Self: Unpin, + { + WriteFuture { writer: self, buf } + } + + #[doc = r#" + Flushes the stream to ensure that all buffered contents reach their destination. + + # Examples + + ```no_run + # fn main() -> std::io::Result<()> { async_std::task::block_on(async { + # + use async_std::fs::File; + use async_std::prelude::*; + + let mut file = File::create("a.txt").await?; + + file.write_all(b"hello world").await?; + file.flush().await?; + # + # Ok(()) }) } + ``` + "#] + fn flush(&mut self) -> FlushFuture<'_, Self> + where + Self: Unpin, + { + FlushFuture { writer: self } + } + + #[doc = r#" + Like [`write`], except that it writes from a slice of buffers. + + Data is copied from each buffer in order, with the final buffer read from possibly + being only partially consumed. This method must behave as a call to [`write`] with + the buffers concatenated would. + + The default implementation calls [`write`] with either the first nonempty buffer + provided, or an empty one if none exists. + + [`write`]: #tymethod.write + "#] + fn write_vectored<'a>( + &'a mut self, + bufs: &'a [IoSlice<'a>], + ) -> WriteVectoredFuture<'a, Self> + where + Self: Unpin, + { + WriteVectoredFuture { writer: self, bufs } + } + #[doc = r#" - Extension methods for [`Write`]. + Writes an entire buffer into the byte stream. + + This method will continuously call [`write`] until there is no more data to be + written or an error is returned. This method will not return until the entire + buffer has been successfully written or such an error occurs. + + [`write`]: #tymethod.write + + # Examples + + ```no_run + # fn main() -> std::io::Result<()> { async_std::task::block_on(async { + # + use async_std::fs::File; + use async_std::prelude::*; + + let mut file = File::create("a.txt").await?; + + file.write_all(b"hello world").await?; + # + # Ok(()) }) } + ``` + + [`write`]: #tymethod.write + "#] + fn write_all<'a>( + &'a mut self, + buf: &'a [u8], + ) -> WriteAllFuture<'a, Self> + where + Self: Unpin, + { + WriteAllFuture { writer: self, buf } + } + + #[doc = r#" + Writes a formatted string into this writer, returning any error encountered. + + This method will continuously call [`write`] until there is no more data to be + written or an error is returned. This future will not resolve until the entire + buffer has been successfully written or such an error occurs. + + [`write`]: #tymethod.write + + # Examples + + ```no_run + # fn main() -> std::io::Result<()> { async_std::task::block_on(async { + # + use async_std::io::prelude::*; + use async_std::fs::File; + + let mut buffer = File::create("foo.txt").await?; - [`Write`]: ../trait.Write.html + // this call + write!(buffer, "{:.*}", 2, 1.234567).await?; + // turns into this: + buffer.write_fmt(format_args!("{:.*}", 2, 1.234567)).await?; + # + # Ok(()) }) } + ``` "#] - pub trait WriteExt: Write { - #[doc = r#" - Writes some bytes into the byte stream. - - Returns the number of bytes written from the start of the buffer. - - If the return value is `Ok(n)` then it must be guaranteed that - `0 <= n <= buf.len()`. A return value of `0` typically means that the underlying - object is no longer able to accept bytes and will likely not be able to in the - future as well, or that the buffer provided is empty. - - # Examples - - ```no_run - # fn main() -> std::io::Result<()> { async_std::task::block_on(async { - # - use async_std::fs::File; - use async_std::prelude::*; - - let mut file = File::create("a.txt").await?; - - let n = file.write(b"hello world").await?; - # - # Ok(()) }) } - ``` - "#] - fn write<'a>( - &'a mut self, - buf: &'a [u8], - ) -> WriteFuture<'a, Self> - where - Self: Unpin, - { - WriteFuture { writer: self, buf } - } - - #[doc = r#" - Flushes the stream to ensure that all buffered contents reach their destination. - - # Examples - - ```no_run - # fn main() -> std::io::Result<()> { async_std::task::block_on(async { - # - use async_std::fs::File; - use async_std::prelude::*; - - let mut file = File::create("a.txt").await?; - - file.write_all(b"hello world").await?; - file.flush().await?; - # - # Ok(()) }) } - ``` - "#] - fn flush(&mut self) -> FlushFuture<'_, Self> - where - Self: Unpin, - { - FlushFuture { writer: self } - } - - #[doc = r#" - Like [`write`], except that it writes from a slice of buffers. - - Data is copied from each buffer in order, with the final buffer read from possibly - being only partially consumed. This method must behave as a call to [`write`] with - the buffers concatenated would. - - The default implementation calls [`write`] with either the first nonempty buffer - provided, or an empty one if none exists. - - [`write`]: #tymethod.write - "#] - fn write_vectored<'a>( - &'a mut self, - bufs: &'a [IoSlice<'a>], - ) -> WriteVectoredFuture<'a, Self> - where - Self: Unpin, - { - WriteVectoredFuture { writer: self, bufs } - } - - #[doc = r#" - Writes an entire buffer into the byte stream. - - This method will continuously call [`write`] until there is no more data to be - written or an error is returned. This method will not return until the entire - buffer has been successfully written or such an error occurs. - - [`write`]: #tymethod.write - - # Examples - - ```no_run - # fn main() -> std::io::Result<()> { async_std::task::block_on(async { - # - use async_std::fs::File; - use async_std::prelude::*; - - let mut file = File::create("a.txt").await?; - - file.write_all(b"hello world").await?; - # - # Ok(()) }) } - ``` - - [`write`]: #tymethod.write - "#] - fn write_all<'a>( - &'a mut self, - buf: &'a [u8], - ) -> WriteAllFuture<'a, Self> - where - Self: Unpin, - { - WriteAllFuture { writer: self, buf } - } - - #[doc = r#" - Writes a formatted string into this writer, returning any error encountered. - - This method will continuously call [`write`] until there is no more data to be - written or an error is returned. This future will not resolve until the entire - buffer has been successfully written or such an error occurs. - - [`write`]: #tymethod.write - - # Examples - - ```no_run - # fn main() -> std::io::Result<()> { async_std::task::block_on(async { - # - use async_std::io::prelude::*; - use async_std::fs::File; - - let mut buffer = File::create("foo.txt").await?; - - // this call - write!(buffer, "{:.*}", 2, 1.234567).await?; - // turns into this: - buffer.write_fmt(format_args!("{:.*}", 2, 1.234567)).await?; - # - # Ok(()) }) } - ``` - "#] - fn write_fmt<'a>( - &'a mut self, - fmt: std::fmt::Arguments<'_>, - ) -> WriteFmtFuture<'a, Self> - where - Self: Unpin, - { - // In order to not have to implement an async version of `fmt` including private types - // and all, we convert `Arguments` to a `Result>` and pass that to the Future. - // Doing an owned conversion saves us from juggling references. - let mut string = String::new(); - let res = std::fmt::write(&mut string, fmt) - .map(|_| string.into_bytes()) - .map_err(|_| io::Error::new(io::ErrorKind::Other, "formatter error")); - WriteFmtFuture { writer: self, res: Some(res), buffer: None, amt: 0 } - } + fn write_fmt<'a>( + &'a mut self, + fmt: std::fmt::Arguments<'_>, + ) -> WriteFmtFuture<'a, Self> + where + Self: Unpin, + { + // In order to not have to implement an async version of `fmt` including private types + // and all, we convert `Arguments` to a `Result>` and pass that to the Future. + // Doing an owned conversion saves us from juggling references. + let mut string = String::new(); + let res = std::fmt::write(&mut string, fmt) + .map(|_| string.into_bytes()) + .map_err(|_| io::Error::new(io::ErrorKind::Other, "formatter error")); + WriteFmtFuture { writer: self, res: Some(res), buffer: None, amt: 0 } } +} impl WriteExt for T {} diff --git a/src/stream/stream/mod.rs b/src/stream/stream/mod.rs index 25aadfac..b0bf1f33 100644 --- a/src/stream/stream/mod.rs +++ b/src/stream/stream/mod.rs @@ -145,2166 +145,2166 @@ cfg_unstable! { pub use futures_core::stream::Stream as Stream; - #[doc = r#" - Extension methods for [`Stream`]. - - [`Stream`]: ../stream/trait.Stream.html - "#] - pub trait StreamExt: Stream { - #[doc = r#" - Advances the stream and returns the next value. +#[doc = r#" + Extension methods for [`Stream`]. - Returns [`None`] when iteration is finished. Individual stream implementations may - choose to resume iteration, and so calling `next()` again may or may not eventually - start returning more values. - - [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None - - # Examples - - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + [`Stream`]: ../stream/trait.Stream.html +"#] +pub trait StreamExt: Stream { + #[doc = r#" + Advances the stream and returns the next value. - let mut s = stream::once(7); + Returns [`None`] when iteration is finished. Individual stream implementations may + choose to resume iteration, and so calling `next()` again may or may not eventually + start returning more values. - assert_eq!(s.next().await, Some(7)); - assert_eq!(s.next().await, None); - # - # }) } - ``` - "#] - fn next(&mut self) -> NextFuture<'_, Self> - where - Self: Unpin, - { - NextFuture { stream: self } - } + [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None - #[doc = r#" - Creates a stream that yields its first `n` elements. + # Examples - # Examples + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + let mut s = stream::once(7); - let mut s = stream::repeat(9).take(3); + assert_eq!(s.next().await, Some(7)); + assert_eq!(s.next().await, None); + # + # }) } + ``` + "#] + fn next(&mut self) -> NextFuture<'_, Self> + where + Self: Unpin, + { + NextFuture { stream: self } + } - while let Some(v) = s.next().await { - assert_eq!(v, 9); - } - # - # }) } - ``` - "#] - fn take(self, n: usize) -> Take - where - Self: Sized, - { - Take::new(self, n) - } + #[doc = r#" + Creates a stream that yields its first `n` elements. - #[doc = r#" - Creates a stream that yields elements based on a predicate. + # Examples - # Examples + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + let mut s = stream::repeat(9).take(3); - let s = stream::from_iter(vec![1, 2, 3, 4]); - let mut s = s.take_while(|x| x < &3 ); - - assert_eq!(s.next().await, Some(1)); - assert_eq!(s.next().await, Some(2)); - assert_eq!(s.next().await, None); - # - # }) } - ``` - "#] - fn take_while

(self, predicate: P) -> TakeWhile - where - Self: Sized, - P: FnMut(&Self::Item) -> bool, - { - TakeWhile::new(self, predicate) + while let Some(v) = s.next().await { + assert_eq!(v, 9); } + # + # }) } + ``` + "#] + fn take(self, n: usize) -> Take + where + Self: Sized, + { + Take::new(self, n) + } - #[doc = r#" - Limit the amount of items yielded per timeslice in a stream. - - This stream does not drop any items, but will only limit the rate at which items pass through. - # Examples - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; - use std::time::{Duration, Instant}; + #[doc = r#" + Creates a stream that yields elements based on a predicate. - let start = Instant::now(); + # Examples - // emit value every 5 milliseconds - let s = stream::interval(Duration::from_millis(5)).take(2); + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - // throttle for 10 milliseconds - let mut s = s.throttle(Duration::from_millis(10)); + let s = stream::from_iter(vec![1, 2, 3, 4]); + let mut s = s.take_while(|x| x < &3 ); - s.next().await; - assert!(start.elapsed().as_millis() >= 5); + assert_eq!(s.next().await, Some(1)); + assert_eq!(s.next().await, Some(2)); + assert_eq!(s.next().await, None); + # + # }) } + ``` + "#] + fn take_while

(self, predicate: P) -> TakeWhile + where + Self: Sized, + P: FnMut(&Self::Item) -> bool, + { + TakeWhile::new(self, predicate) + } - s.next().await; - assert!(start.elapsed().as_millis() >= 15); + #[doc = r#" + Limit the amount of items yielded per timeslice in a stream. - s.next().await; - assert!(start.elapsed().as_millis() >= 25); - # - # }) } - ``` - "#] - #[cfg(feature = "unstable")] - #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - fn throttle(self, d: Duration) -> Throttle - where - Self: Sized, - { - Throttle::new(self, d) - } + This stream does not drop any items, but will only limit the rate at which items pass through. + # Examples + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; + use std::time::{Duration, Instant}; - #[doc = r#" - Creates a stream that yields each `step`th element. + let start = Instant::now(); - # Panics + // emit value every 5 milliseconds + let s = stream::interval(Duration::from_millis(5)).take(2); - This method will panic if the given step is `0`. + // throttle for 10 milliseconds + let mut s = s.throttle(Duration::from_millis(10)); - # Examples + s.next().await; + assert!(start.elapsed().as_millis() >= 5); - Basic usage: + s.next().await; + assert!(start.elapsed().as_millis() >= 15); - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + s.next().await; + assert!(start.elapsed().as_millis() >= 25); + # + # }) } + ``` + "#] + #[cfg(feature = "unstable")] + #[cfg_attr(feature = "docs", doc(cfg(unstable)))] + fn throttle(self, d: Duration) -> Throttle + where + Self: Sized, + { + Throttle::new(self, d) + } - let s = stream::from_iter(vec![0u8, 1, 2, 3, 4]); - let mut stepped = s.step_by(2); + #[doc = r#" + Creates a stream that yields each `step`th element. - assert_eq!(stepped.next().await, Some(0)); - assert_eq!(stepped.next().await, Some(2)); - assert_eq!(stepped.next().await, Some(4)); - assert_eq!(stepped.next().await, None); + # Panics - # - # }) } - ``` - "#] - fn step_by(self, step: usize) -> StepBy - where - Self: Sized, - { - StepBy::new(self, step) - } + This method will panic if the given step is `0`. - #[doc = r#" - Takes two streams and creates a new stream over both in sequence. + # Examples - # Examples + Basic usage: - Basic usage: + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + let s = stream::from_iter(vec![0u8, 1, 2, 3, 4]); + let mut stepped = s.step_by(2); - let first = stream::from_iter(vec![0u8, 1]); - let second = stream::from_iter(vec![2, 3]); - let mut c = first.chain(second); - - assert_eq!(c.next().await, Some(0)); - assert_eq!(c.next().await, Some(1)); - assert_eq!(c.next().await, Some(2)); - assert_eq!(c.next().await, Some(3)); - assert_eq!(c.next().await, None); - - # - # }) } - ``` - "#] - fn chain(self, other: U) -> Chain - where - Self: Sized, - U: Stream + Sized, - { - Chain::new(self, other) - } + assert_eq!(stepped.next().await, Some(0)); + assert_eq!(stepped.next().await, Some(2)); + assert_eq!(stepped.next().await, Some(4)); + assert_eq!(stepped.next().await, None); - #[doc = r#" - Creates an stream which copies all of its elements. + # + # }) } + ``` + "#] + fn step_by(self, step: usize) -> StepBy + where + Self: Sized, + { + StepBy::new(self, step) + } - # Examples + #[doc = r#" + Takes two streams and creates a new stream over both in sequence. - Basic usage: + # Examples - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + Basic usage: - let v = stream::from_iter(vec![&1, &2, &3]); + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - let mut v_cloned = v.cloned(); + let first = stream::from_iter(vec![0u8, 1]); + let second = stream::from_iter(vec![2, 3]); + let mut c = first.chain(second); - assert_eq!(v_cloned.next().await, Some(1)); - assert_eq!(v_cloned.next().await, Some(2)); - assert_eq!(v_cloned.next().await, Some(3)); - assert_eq!(v_cloned.next().await, None); - - # - # }) } - ``` - "#] - fn cloned<'a, T>(self) -> Cloned - where - Self: Sized + Stream, - T: Clone + 'a, - { - Cloned::new(self) - } + assert_eq!(c.next().await, Some(0)); + assert_eq!(c.next().await, Some(1)); + assert_eq!(c.next().await, Some(2)); + assert_eq!(c.next().await, Some(3)); + assert_eq!(c.next().await, None); + # + # }) } + ``` + "#] + fn chain(self, other: U) -> Chain + where + Self: Sized, + U: Stream + Sized, + { + Chain::new(self, other) + } #[doc = r#" - Creates an stream which copies all of its elements. - - # Examples - - Basic usage: - - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + Creates an stream which copies all of its elements. - let s = stream::from_iter(vec![&1, &2, &3]); - let mut s_copied = s.copied(); - - assert_eq!(s_copied.next().await, Some(1)); - assert_eq!(s_copied.next().await, Some(2)); - assert_eq!(s_copied.next().await, Some(3)); - assert_eq!(s_copied.next().await, None); - # - # }) } - ``` - "#] - fn copied<'a, T>(self) -> Copied - where - Self: Sized + Stream, - T: Copy + 'a, - { - Copied::new(self) - } + # Examples - #[doc = r#" - Creates a stream that yields the provided values infinitely and in order. + Basic usage: - # Examples + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - Basic usage: + let v = stream::from_iter(vec![&1, &2, &3]); - ``` - # async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + let mut v_cloned = v.cloned(); - let mut s = stream::once(7).cycle(); - - assert_eq!(s.next().await, Some(7)); - assert_eq!(s.next().await, Some(7)); - assert_eq!(s.next().await, Some(7)); - assert_eq!(s.next().await, Some(7)); - assert_eq!(s.next().await, Some(7)); - # - # }) - ``` - "#] - fn cycle(self) -> Cycle - where - Self: Clone + Sized, - { - Cycle::new(self) - } + assert_eq!(v_cloned.next().await, Some(1)); + assert_eq!(v_cloned.next().await, Some(2)); + assert_eq!(v_cloned.next().await, Some(3)); + assert_eq!(v_cloned.next().await, None); - #[doc = r#" - Creates a stream that gives the current element's count as well as the next value. + # + # }) } + ``` + "#] + fn cloned<'a, T>(self) -> Cloned + where + Self: Sized + Stream, + T: Clone + 'a, + { + Cloned::new(self) + } - # Overflow behaviour. - This combinator does no guarding against overflows. + #[doc = r#" + Creates an stream which copies all of its elements. - # Examples + # Examples - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + Basic usage: - let s = stream::from_iter(vec!['a', 'b', 'c']); - let mut s = s.enumerate(); - - assert_eq!(s.next().await, Some((0, 'a'))); - assert_eq!(s.next().await, Some((1, 'b'))); - assert_eq!(s.next().await, Some((2, 'c'))); - assert_eq!(s.next().await, None); - # - # }) } - ``` - "#] - fn enumerate(self) -> Enumerate - where - Self: Sized, - { - Enumerate::new(self) - } + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - #[doc = r#" - Creates a stream that is delayed before it starts yielding items. + let s = stream::from_iter(vec![&1, &2, &3]); + let mut s_copied = s.copied(); - # Examples + assert_eq!(s_copied.next().await, Some(1)); + assert_eq!(s_copied.next().await, Some(2)); + assert_eq!(s_copied.next().await, Some(3)); + assert_eq!(s_copied.next().await, None); + # + # }) } + ``` + "#] + fn copied<'a, T>(self) -> Copied + where + Self: Sized + Stream, + T: Copy + 'a, + { + Copied::new(self) + } - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; - use std::time::{Duration, Instant}; - - let start = Instant::now(); - let mut s = stream::from_iter(vec![0u8, 1, 2]).delay(Duration::from_millis(200)); - - assert_eq!(s.next().await, Some(0)); - // The first time will take more than 200ms due to delay. - assert!(start.elapsed().as_millis() >= 200); - - assert_eq!(s.next().await, Some(1)); - // There will be no delay after the first time. - assert!(start.elapsed().as_millis() < 400); - - assert_eq!(s.next().await, Some(2)); - assert!(start.elapsed().as_millis() < 400); - - assert_eq!(s.next().await, None); - assert!(start.elapsed().as_millis() < 400); - # - # }) } - ``` - "#] - #[cfg(any(feature = "unstable", feature = "docs"))] - #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - fn delay(self, dur: std::time::Duration) -> Delay - where - Self: Sized, - { - Delay::new(self, dur) - } + #[doc = r#" + Creates a stream that yields the provided values infinitely and in order. - #[doc = r#" - Takes a closure and creates a stream that calls that closure on every element of this stream. + # Examples - # Examples + Basic usage: - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + ``` + # async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - let s = stream::from_iter(vec![1, 2, 3]); - let mut s = s.map(|x| 2 * x); + let mut s = stream::once(7).cycle(); - assert_eq!(s.next().await, Some(2)); - assert_eq!(s.next().await, Some(4)); - assert_eq!(s.next().await, Some(6)); - assert_eq!(s.next().await, None); + assert_eq!(s.next().await, Some(7)); + assert_eq!(s.next().await, Some(7)); + assert_eq!(s.next().await, Some(7)); + assert_eq!(s.next().await, Some(7)); + assert_eq!(s.next().await, Some(7)); + # + # }) + ``` + "#] + fn cycle(self) -> Cycle + where + Self: Clone + Sized, + { + Cycle::new(self) + } - # - # }) } - ``` - "#] - fn map(self, f: F) -> Map - where - Self: Sized, - F: FnMut(Self::Item) -> B, - { - Map::new(self, f) - } + #[doc = r#" + Creates a stream that gives the current element's count as well as the next value. - #[doc = r#" - A combinator that does something with each element in the stream, passing the value - on. + # Overflow behaviour. - # Examples + This combinator does no guarding against overflows. - Basic usage: + # Examples - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - let s = stream::from_iter(vec![1, 2, 3, 4, 5]); - - let sum = s - .inspect(|x| println!("about to filter {}", x)) - .filter(|x| x % 2 == 0) - .inspect(|x| println!("made it through filter: {}", x)) - .fold(0, |sum, i| sum + i) - .await; - - assert_eq!(sum, 6); - # - # }) } - ``` - "#] - fn inspect(self, f: F) -> Inspect - where - Self: Sized, - F: FnMut(&Self::Item), - { - Inspect::new(self, f) - } + let s = stream::from_iter(vec!['a', 'b', 'c']); + let mut s = s.enumerate(); - #[doc = r#" - Returns the last element of the stream. + assert_eq!(s.next().await, Some((0, 'a'))); + assert_eq!(s.next().await, Some((1, 'b'))); + assert_eq!(s.next().await, Some((2, 'c'))); + assert_eq!(s.next().await, None); + # + # }) } + ``` + "#] + fn enumerate(self) -> Enumerate + where + Self: Sized, + { + Enumerate::new(self) + } - # Examples + #[doc = r#" + Creates a stream that is delayed before it starts yielding items. - Basic usage: + # Examples - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; + use std::time::{Duration, Instant}; - let s = stream::from_iter(vec![1, 2, 3]); + let start = Instant::now(); + let mut s = stream::from_iter(vec![0u8, 1, 2]).delay(Duration::from_millis(200)); - let last = s.last().await; - assert_eq!(last, Some(3)); - # - # }) } - ``` + assert_eq!(s.next().await, Some(0)); + // The first time will take more than 200ms due to delay. + assert!(start.elapsed().as_millis() >= 200); - An empty stream will return `None`: - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::stream; - use crate::async_std::prelude::*; - - let s = stream::empty::<()>(); - - let last = s.last().await; - assert_eq!(last, None); - # - # }) } - ``` - "#] - fn last( - self, - ) -> LastFuture - where - Self: Sized, - { - LastFuture::new(self) - } + assert_eq!(s.next().await, Some(1)); + // There will be no delay after the first time. + assert!(start.elapsed().as_millis() < 400); - #[doc = r#" - Creates a stream which ends after the first `None`. + assert_eq!(s.next().await, Some(2)); + assert!(start.elapsed().as_millis() < 400); - After a stream returns `None`, future calls may or may not yield `Some(T)` again. - `fuse()` adapts an iterator, ensuring that after a `None` is given, it will always - return `None` forever. + assert_eq!(s.next().await, None); + assert!(start.elapsed().as_millis() < 400); + # + # }) } + ``` + "#] + #[cfg(any(feature = "unstable", feature = "docs"))] + #[cfg_attr(feature = "docs", doc(cfg(unstable)))] + fn delay(self, dur: std::time::Duration) -> Delay + where + Self: Sized, + { + Delay::new(self, dur) + } - # Examples + #[doc = r#" + Takes a closure and creates a stream that calls that closure on every element of this stream. - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + # Examples - let mut s = stream::once(1).fuse(); - assert_eq!(s.next().await, Some(1)); - assert_eq!(s.next().await, None); - assert_eq!(s.next().await, None); - # - # }) } - ``` - "#] - fn fuse(self) -> Fuse - where - Self: Sized, - { - Fuse::new(self) - } + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - #[doc = r#" - Creates a stream that uses a predicate to determine if an element should be yielded. + let s = stream::from_iter(vec![1, 2, 3]); + let mut s = s.map(|x| 2 * x); - # Examples + assert_eq!(s.next().await, Some(2)); + assert_eq!(s.next().await, Some(4)); + assert_eq!(s.next().await, Some(6)); + assert_eq!(s.next().await, None); - Basic usage: + # + # }) } + ``` + "#] + fn map(self, f: F) -> Map + where + Self: Sized, + F: FnMut(Self::Item) -> B, + { + Map::new(self, f) + } - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + #[doc = r#" + A combinator that does something with each element in the stream, passing the value + on. - let s = stream::from_iter(vec![1, 2, 3, 4]); - let mut s = s.filter(|i| i % 2 == 0); - - assert_eq!(s.next().await, Some(2)); - assert_eq!(s.next().await, Some(4)); - assert_eq!(s.next().await, None); - # - # }) } - ``` - "#] - fn filter

(self, predicate: P) -> Filter - where - Self: Sized, - P: FnMut(&Self::Item) -> bool, - { - Filter::new(self, predicate) - } + # Examples - #[doc= r#" - Creates an stream that works like map, but flattens nested structure. + Basic usage: - # Examples + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - Basic usage: + let s = stream::from_iter(vec![1, 2, 3, 4, 5]); - ``` - # async_std::task::block_on(async { + let sum = s + .inspect(|x| println!("about to filter {}", x)) + .filter(|x| x % 2 == 0) + .inspect(|x| println!("made it through filter: {}", x)) + .fold(0, |sum, i| sum + i) + .await; - use async_std::prelude::*; - use async_std::stream; + assert_eq!(sum, 6); + # + # }) } + ``` + "#] + fn inspect(self, f: F) -> Inspect + where + Self: Sized, + F: FnMut(&Self::Item), + { + Inspect::new(self, f) + } - let words = stream::from_iter(&["alpha", "beta", "gamma"]); - - let merged: String = words - .flat_map(|s| stream::from_iter(s.chars())) - .collect().await; - assert_eq!(merged, "alphabetagamma"); - - let d3 = stream::from_iter(&[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]); - let d1: Vec<_> = d3 - .flat_map(|item| stream::from_iter(item)) - .flat_map(|item| stream::from_iter(item)) - .collect().await; - - assert_eq!(d1, [&1, &2, &3, &4, &5, &6, &7, &8]); - # }); - ``` - "#] - #[cfg(feature = "unstable")] - #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - fn flat_map(self, f: F) -> FlatMap - where - Self: Sized, - U: IntoStream, - F: FnMut(Self::Item) -> U, - { - FlatMap::new(self, f) - } + #[doc = r#" + Returns the last element of the stream. - #[doc = r#" - Creates an stream that flattens nested structure. + # Examples - # Examples + Basic usage: - Basic usage: + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - ``` - # async_std::task::block_on(async { + let s = stream::from_iter(vec![1, 2, 3]); - use async_std::prelude::*; - use async_std::stream; + let last = s.last().await; + assert_eq!(last, Some(3)); + # + # }) } + ``` - let inner1 = stream::from_iter(vec![1u8,2,3]); - let inner2 = stream::from_iter(vec![4u8,5,6]); - let s = stream::from_iter(vec![inner1, inner2]); + An empty stream will return `None`: + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::stream; + use crate::async_std::prelude::*; - let v: Vec<_> = s.flatten().collect().await; + let s = stream::empty::<()>(); - assert_eq!(v, vec![1,2,3,4,5,6]); + let last = s.last().await; + assert_eq!(last, None); + # + # }) } + ``` + "#] + fn last( + self, + ) -> LastFuture + where + Self: Sized, + { + LastFuture::new(self) + } - # }); - "#] - #[cfg(feature = "unstable")] - #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - fn flatten(self) -> Flatten - where - Self: Sized, - Self::Item: IntoStream, - { - Flatten::new(self) - } + #[doc = r#" + Creates a stream which ends after the first `None`. + + After a stream returns `None`, future calls may or may not yield `Some(T)` again. + `fuse()` adapts an iterator, ensuring that after a `None` is given, it will always + return `None` forever. + + # Examples + + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; + + let mut s = stream::once(1).fuse(); + assert_eq!(s.next().await, Some(1)); + assert_eq!(s.next().await, None); + assert_eq!(s.next().await, None); + # + # }) } + ``` + "#] + fn fuse(self) -> Fuse + where + Self: Sized, + { + Fuse::new(self) + } - #[doc = r#" - Both filters and maps a stream. + #[doc = r#" + Creates a stream that uses a predicate to determine if an element should be yielded. - # Examples + # Examples - Basic usage: + Basic usage: - ``` - # fn main() { async_std::task::block_on(async { - # + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - use async_std::prelude::*; - use async_std::stream; + let s = stream::from_iter(vec![1, 2, 3, 4]); + let mut s = s.filter(|i| i % 2 == 0); - let s = stream::from_iter(vec!["1", "lol", "3", "NaN", "5"]); + assert_eq!(s.next().await, Some(2)); + assert_eq!(s.next().await, Some(4)); + assert_eq!(s.next().await, None); + # + # }) } + ``` + "#] + fn filter

(self, predicate: P) -> Filter + where + Self: Sized, + P: FnMut(&Self::Item) -> bool, + { + Filter::new(self, predicate) + } - let mut parsed = s.filter_map(|a| a.parse::().ok()); + #[doc= r#" + Creates an stream that works like map, but flattens nested structure. - let one = parsed.next().await; - assert_eq!(one, Some(1)); + # Examples - let three = parsed.next().await; - assert_eq!(three, Some(3)); + Basic usage: - let five = parsed.next().await; - assert_eq!(five, Some(5)); + ``` + # async_std::task::block_on(async { - let end = parsed.next().await; - assert_eq!(end, None); - # - # }) } - ``` - "#] - fn filter_map(self, f: F) -> FilterMap - where - Self: Sized, - F: FnMut(Self::Item) -> Option, - { - FilterMap::new(self, f) - } + use async_std::prelude::*; + use async_std::stream; - #[doc = r#" - Returns the element that gives the minimum value with respect to the - specified key function. If several elements are equally minimum, - the first element is returned. If the stream is empty, `None` is returned. + let words = stream::from_iter(&["alpha", "beta", "gamma"]); - # Examples + let merged: String = words + .flat_map(|s| stream::from_iter(s.chars())) + .collect().await; + assert_eq!(merged, "alphabetagamma"); - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + let d3 = stream::from_iter(&[[[1, 2], [3, 4]], [[5, 6], [7, 8]]]); + let d1: Vec<_> = d3 + .flat_map(|item| stream::from_iter(item)) + .flat_map(|item| stream::from_iter(item)) + .collect().await; - let s = stream::from_iter(vec![-1isize, 2, -3]); - - let min = s.clone().min_by_key(|x| x.abs()).await; - assert_eq!(min, Some(-1)); - - let min = stream::empty::().min_by_key(|x| x.abs()).await; - assert_eq!(min, None); - # - # }) } - ``` - "#] - fn min_by_key( - self, - key_by: F, - ) -> MinByKeyFuture + assert_eq!(d1, [&1, &2, &3, &4, &5, &6, &7, &8]); + # }); + ``` + "#] + #[cfg(feature = "unstable")] + #[cfg_attr(feature = "docs", doc(cfg(unstable)))] + fn flat_map(self, f: F) -> FlatMap where Self: Sized, - B: Ord, - F: FnMut(&Self::Item) -> B, - { - MinByKeyFuture::new(self, key_by) - } + U: IntoStream, + F: FnMut(Self::Item) -> U, + { + FlatMap::new(self, f) + } - #[doc = r#" - Returns the element that gives the maximum value with respect to the - specified key function. If several elements are equally maximum, - the first element is returned. If the stream is empty, `None` is returned. + #[doc = r#" + Creates an stream that flattens nested structure. - # Examples + # Examples - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + Basic usage: - let s = stream::from_iter(vec![-3_i32, 0, 1, 5, -10]); - - let max = s.clone().max_by_key(|x| x.abs()).await; - assert_eq!(max, Some(-10)); - - let max = stream::empty::().max_by_key(|x| x.abs()).await; - assert_eq!(max, None); - # - # }) } - ``` - "#] - fn max_by_key( - self, - key_by: F, - ) -> MaxByKeyFuture - where - Self: Sized, - B: Ord, - F: FnMut(&Self::Item) -> B, - { - MaxByKeyFuture::new(self, key_by) - } + ``` + # async_std::task::block_on(async { - #[doc = r#" - Returns the element that gives the minimum value with respect to the - specified comparison function. If several elements are equally minimum, - the first element is returned. If the stream is empty, `None` is returned. + use async_std::prelude::*; + use async_std::stream; - # Examples + let inner1 = stream::from_iter(vec![1u8,2,3]); + let inner2 = stream::from_iter(vec![4u8,5,6]); + let s = stream::from_iter(vec![inner1, inner2]); - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + let v: Vec<_> = s.flatten().collect().await; - let s = stream::from_iter(vec![1u8, 2, 3]); + assert_eq!(v, vec![1,2,3,4,5,6]); - let min = s.clone().min_by(|x, y| x.cmp(y)).await; - assert_eq!(min, Some(1)); + # }); + "#] + #[cfg(feature = "unstable")] + #[cfg_attr(feature = "docs", doc(cfg(unstable)))] + fn flatten(self) -> Flatten + where + Self: Sized, + Self::Item: IntoStream, + { + Flatten::new(self) + } - let min = s.min_by(|x, y| y.cmp(x)).await; - assert_eq!(min, Some(3)); + #[doc = r#" + Both filters and maps a stream. - let min = stream::empty::().min_by(|x, y| x.cmp(y)).await; - assert_eq!(min, None); - # - # }) } - ``` - "#] - fn min_by( - self, - compare: F, - ) -> MinByFuture - where - Self: Sized, - F: FnMut(&Self::Item, &Self::Item) -> Ordering, - { - MinByFuture::new(self, compare) - } + # Examples - #[doc = r#" - Returns the element that gives the maximum value. If several elements are equally maximum, - the first element is returned. If the stream is empty, `None` is returned. + Basic usage: - # Examples + ``` + # fn main() { async_std::task::block_on(async { + # - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + use async_std::prelude::*; + use async_std::stream; - let s = stream::from_iter(vec![1usize, 2, 3]); + let s = stream::from_iter(vec!["1", "lol", "3", "NaN", "5"]); - let max = s.clone().max().await; - assert_eq!(max, Some(3)); + let mut parsed = s.filter_map(|a| a.parse::().ok()); - let max = stream::empty::().max().await; - assert_eq!(max, None); - # - # }) } - ``` - "#] - fn max( - self, - ) -> MaxFuture - where - Self: Sized, - Self::Item: Ord, - { - MaxFuture::new(self) - } + let one = parsed.next().await; + assert_eq!(one, Some(1)); - #[doc = r#" - Returns the element that gives the minimum value. If several elements are equally minimum, - the first element is returned. If the stream is empty, `None` is returned. + let three = parsed.next().await; + assert_eq!(three, Some(3)); - # Examples + let five = parsed.next().await; + assert_eq!(five, Some(5)); - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + let end = parsed.next().await; + assert_eq!(end, None); + # + # }) } + ``` + "#] + fn filter_map(self, f: F) -> FilterMap + where + Self: Sized, + F: FnMut(Self::Item) -> Option, + { + FilterMap::new(self, f) + } - let s = stream::from_iter(vec![1usize, 2, 3]); + #[doc = r#" + Returns the element that gives the minimum value with respect to the + specified key function. If several elements are equally minimum, + the first element is returned. If the stream is empty, `None` is returned. - let min = s.clone().min().await; - assert_eq!(min, Some(1)); + # Examples - let min = stream::empty::().min().await; - assert_eq!(min, None); - # - # }) } - ``` - "#] - fn min( - self, - ) -> MinFuture - where - Self: Sized, - Self::Item: Ord, - { - MinFuture::new(self) - } + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - #[doc = r#" - Returns the element that gives the maximum value with respect to the - specified comparison function. If several elements are equally maximum, - the first element is returned. If the stream is empty, `None` is returned. + let s = stream::from_iter(vec![-1isize, 2, -3]); - # Examples + let min = s.clone().min_by_key(|x| x.abs()).await; + assert_eq!(min, Some(-1)); - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + let min = stream::empty::().min_by_key(|x| x.abs()).await; + assert_eq!(min, None); + # + # }) } + ``` + "#] + fn min_by_key( + self, + key_by: F, + ) -> MinByKeyFuture + where + Self: Sized, + B: Ord, + F: FnMut(&Self::Item) -> B, + { + MinByKeyFuture::new(self, key_by) + } - let s = stream::from_iter(vec![1u8, 2, 3]); + #[doc = r#" + Returns the element that gives the maximum value with respect to the + specified key function. If several elements are equally maximum, + the first element is returned. If the stream is empty, `None` is returned. - let max = s.clone().max_by(|x, y| x.cmp(y)).await; - assert_eq!(max, Some(3)); + # Examples - let max = s.max_by(|x, y| y.cmp(x)).await; - assert_eq!(max, Some(1)); + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - let max = stream::empty::().max_by(|x, y| x.cmp(y)).await; - assert_eq!(max, None); - # - # }) } - ``` - "#] - fn max_by( - self, - compare: F, - ) -> MaxByFuture - where - Self: Sized, - F: FnMut(&Self::Item, &Self::Item) -> Ordering, - { - MaxByFuture::new(self, compare) - } + let s = stream::from_iter(vec![-3_i32, 0, 1, 5, -10]); - #[doc = r#" - Returns the nth element of the stream. + let max = s.clone().max_by_key(|x| x.abs()).await; + assert_eq!(max, Some(-10)); - # Examples + let max = stream::empty::().max_by_key(|x| x.abs()).await; + assert_eq!(max, None); + # + # }) } + ``` + "#] + fn max_by_key( + self, + key_by: F, + ) -> MaxByKeyFuture + where + Self: Sized, + B: Ord, + F: FnMut(&Self::Item) -> B, + { + MaxByKeyFuture::new(self, key_by) + } - Basic usage: + #[doc = r#" + Returns the element that gives the minimum value with respect to the + specified comparison function. If several elements are equally minimum, + the first element is returned. If the stream is empty, `None` is returned. - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + # Examples - let mut s = stream::from_iter(vec![1u8, 2, 3]); + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - let second = s.nth(1).await; - assert_eq!(second, Some(2)); - # - # }) } - ``` - Calling `nth()` multiple times: + let s = stream::from_iter(vec![1u8, 2, 3]); - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::stream; - use async_std::prelude::*; + let min = s.clone().min_by(|x, y| x.cmp(y)).await; + assert_eq!(min, Some(1)); - let mut s = stream::from_iter(vec![1u8, 2, 3]); + let min = s.min_by(|x, y| y.cmp(x)).await; + assert_eq!(min, Some(3)); - let second = s.nth(0).await; - assert_eq!(second, Some(1)); + let min = stream::empty::().min_by(|x, y| x.cmp(y)).await; + assert_eq!(min, None); + # + # }) } + ``` + "#] + fn min_by( + self, + compare: F, + ) -> MinByFuture + where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering, + { + MinByFuture::new(self, compare) + } - let second = s.nth(0).await; - assert_eq!(second, Some(2)); - # - # }) } - ``` - Returning `None` if the stream finished before returning `n` elements: - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + #[doc = r#" + Returns the element that gives the maximum value. If several elements are equally maximum, + the first element is returned. If the stream is empty, `None` is returned. - let mut s = stream::from_iter(vec![1u8, 2, 3]); - - let fourth = s.nth(4).await; - assert_eq!(fourth, None); - # - # }) } - ``` - "#] - fn nth( - &mut self, - n: usize, - ) -> NthFuture<'_, Self> - where - Self: Unpin + Sized, - { - NthFuture::new(self, n) - } + # Examples - #[doc = r#" - Tests if every element of the stream matches a predicate. + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - `all()` takes a closure that returns `true` or `false`. It applies - this closure to each element of the stream, and if they all return - `true`, then so does `all()`. If any of them return `false`, it - returns `false`. + let s = stream::from_iter(vec![1usize, 2, 3]); - `all()` is short-circuiting; in other words, it will stop processing - as soon as it finds a `false`, given that no matter what else happens, - the result will also be `false`. + let max = s.clone().max().await; + assert_eq!(max, Some(3)); - An empty stream returns `true`. + let max = stream::empty::().max().await; + assert_eq!(max, None); + # + # }) } + ``` + "#] + fn max( + self, + ) -> MaxFuture + where + Self: Sized, + Self::Item: Ord, + { + MaxFuture::new(self) + } - # Examples + #[doc = r#" + Returns the element that gives the minimum value. If several elements are equally minimum, + the first element is returned. If the stream is empty, `None` is returned. - Basic usage: + # Examples - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - let mut s = stream::repeat::(42).take(3); - assert!(s.all(|x| x == 42).await); + let s = stream::from_iter(vec![1usize, 2, 3]); - # - # }) } - ``` + let min = s.clone().min().await; + assert_eq!(min, Some(1)); - Empty stream: + let min = stream::empty::().min().await; + assert_eq!(min, None); + # + # }) } + ``` + "#] + fn min( + self, + ) -> MinFuture + where + Self: Sized, + Self::Item: Ord, + { + MinFuture::new(self) + } - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + #[doc = r#" + Returns the element that gives the maximum value with respect to the + specified comparison function. If several elements are equally maximum, + the first element is returned. If the stream is empty, `None` is returned. - let mut s = stream::empty::(); - assert!(s.all(|_| false).await); - # - # }) } - ``` - "#] - #[inline] - fn all( - &mut self, - f: F, - ) -> AllFuture<'_, Self, F, Self::Item> - where - Self: Unpin + Sized, - F: FnMut(Self::Item) -> bool, - { - AllFuture::new(self, f) - } + # Examples - #[doc = r#" - Searches for an element in a stream that satisfies a predicate. + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - # Examples + let s = stream::from_iter(vec![1u8, 2, 3]); - Basic usage: + let max = s.clone().max_by(|x, y| x.cmp(y)).await; + assert_eq!(max, Some(3)); - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + let max = s.max_by(|x, y| y.cmp(x)).await; + assert_eq!(max, Some(1)); - let mut s = stream::from_iter(vec![1u8, 2, 3]); - let res = s.find(|x| *x == 2).await; - assert_eq!(res, Some(2)); - # - # }) } - ``` + let max = stream::empty::().max_by(|x, y| x.cmp(y)).await; + assert_eq!(max, None); + # + # }) } + ``` + "#] + fn max_by( + self, + compare: F, + ) -> MaxByFuture + where + Self: Sized, + F: FnMut(&Self::Item, &Self::Item) -> Ordering, + { + MaxByFuture::new(self, compare) + } - Resuming after a first find: + #[doc = r#" + Returns the nth element of the stream. + + # Examples + + Basic usage: + + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; + + let mut s = stream::from_iter(vec![1u8, 2, 3]); + + let second = s.nth(1).await; + assert_eq!(second, Some(2)); + # + # }) } + ``` + Calling `nth()` multiple times: + + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::stream; + use async_std::prelude::*; + + let mut s = stream::from_iter(vec![1u8, 2, 3]); + + let second = s.nth(0).await; + assert_eq!(second, Some(1)); + + let second = s.nth(0).await; + assert_eq!(second, Some(2)); + # + # }) } + ``` + Returning `None` if the stream finished before returning `n` elements: + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; + + let mut s = stream::from_iter(vec![1u8, 2, 3]); + + let fourth = s.nth(4).await; + assert_eq!(fourth, None); + # + # }) } + ``` + "#] + fn nth( + &mut self, + n: usize, + ) -> NthFuture<'_, Self> + where + Self: Unpin + Sized, + { + NthFuture::new(self, n) + } - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + #[doc = r#" + Tests if every element of the stream matches a predicate. - let mut s= stream::from_iter(vec![1, 2, 3]); - let res = s.find(|x| *x == 2).await; - assert_eq!(res, Some(2)); - - let next = s.next().await; - assert_eq!(next, Some(3)); - # - # }) } - ``` - "#] - fn find

( - &mut self, - p: P, - ) -> FindFuture<'_, Self, P> - where - Self: Unpin + Sized, - P: FnMut(&Self::Item) -> bool, - { - FindFuture::new(self, p) - } + `all()` takes a closure that returns `true` or `false`. It applies + this closure to each element of the stream, and if they all return + `true`, then so does `all()`. If any of them return `false`, it + returns `false`. - #[doc = r#" - Applies function to the elements of stream and returns the first non-none result. + `all()` is short-circuiting; in other words, it will stop processing + as soon as it finds a `false`, given that no matter what else happens, + the result will also be `false`. - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + An empty stream returns `true`. - let mut s = stream::from_iter(vec!["lol", "NaN", "2", "5"]); - let first_number = s.find_map(|s| s.parse().ok()).await; - - assert_eq!(first_number, Some(2)); - # - # }) } - ``` - "#] - fn find_map( - &mut self, - f: F, - ) -> FindMapFuture<'_, Self, F> - where - Self: Unpin + Sized, - F: FnMut(Self::Item) -> Option, - { - FindMapFuture::new(self, f) - } + # Examples - #[doc = r#" - A combinator that applies a function to every element in a stream - producing a single, final value. + Basic usage: - # Examples + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - Basic usage: + let mut s = stream::repeat::(42).take(3); + assert!(s.all(|x| x == 42).await); - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + # + # }) } + ``` - let s = stream::from_iter(vec![1u8, 2, 3]); - let sum = s.fold(0, |acc, x| acc + x).await; - - assert_eq!(sum, 6); - # - # }) } - ``` - "#] - fn fold( - self, - init: B, - f: F, - ) -> FoldFuture - where - Self: Sized, - F: FnMut(B, Self::Item) -> B, - { - FoldFuture::new(self, init, f) - } + Empty stream: - #[doc = r#" - A combinator that applies a function to every element in a stream - creating two collections from it. + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - # Examples + let mut s = stream::empty::(); + assert!(s.all(|_| false).await); + # + # }) } + ``` + "#] + #[inline] + fn all( + &mut self, + f: F, + ) -> AllFuture<'_, Self, F, Self::Item> + where + Self: Unpin + Sized, + F: FnMut(Self::Item) -> bool, + { + AllFuture::new(self, f) + } - Basic usage: + #[doc = r#" + Searches for an element in a stream that satisfies a predicate. + + # Examples + + Basic usage: + + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; + + let mut s = stream::from_iter(vec![1u8, 2, 3]); + let res = s.find(|x| *x == 2).await; + assert_eq!(res, Some(2)); + # + # }) } + ``` + + Resuming after a first find: + + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; + + let mut s= stream::from_iter(vec![1, 2, 3]); + let res = s.find(|x| *x == 2).await; + assert_eq!(res, Some(2)); + + let next = s.next().await; + assert_eq!(next, Some(3)); + # + # }) } + ``` + "#] + fn find

( + &mut self, + p: P, + ) -> FindFuture<'_, Self, P> + where + Self: Unpin + Sized, + P: FnMut(&Self::Item) -> bool, + { + FindFuture::new(self, p) + } - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + #[doc = r#" + Applies function to the elements of stream and returns the first non-none result. - let (even, odd): (Vec, Vec) = stream::from_iter(vec![1, 2, 3]) - .partition(|&n| n % 2 == 0).await; - - assert_eq!(even, vec![2]); - assert_eq!(odd, vec![1, 3]); - - # - # }) } - ``` - "#] - #[cfg(feature = "unstable")] - #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - fn partition( - self, - f: F, - ) -> PartitionFuture - where - Self: Sized, - F: FnMut(&Self::Item) -> bool, - B: Default + Extend, - { - PartitionFuture::new(self, f) - } + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - #[doc = r#" - Call a closure on each element of the stream. + let mut s = stream::from_iter(vec!["lol", "NaN", "2", "5"]); + let first_number = s.find_map(|s| s.parse().ok()).await; - # Examples + assert_eq!(first_number, Some(2)); + # + # }) } + ``` + "#] + fn find_map( + &mut self, + f: F, + ) -> FindMapFuture<'_, Self, F> + where + Self: Unpin + Sized, + F: FnMut(Self::Item) -> Option, + { + FindMapFuture::new(self, f) + } - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; - use std::sync::mpsc::channel; + #[doc = r#" + A combinator that applies a function to every element in a stream + producing a single, final value. - let (tx, rx) = channel(); + # Examples - let s = stream::from_iter(vec![1usize, 2, 3]); - let sum = s.for_each(move |x| tx.clone().send(x).unwrap()).await; + Basic usage: - let v: Vec<_> = rx.iter().collect(); + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - assert_eq!(v, vec![1, 2, 3]); - # - # }) } - ``` - "#] - fn for_each( - self, - f: F, - ) -> ForEachFuture - where - Self: Sized, - F: FnMut(Self::Item), - { - ForEachFuture::new(self, f) - } + let s = stream::from_iter(vec![1u8, 2, 3]); + let sum = s.fold(0, |acc, x| acc + x).await; - #[doc = r#" - Tests if any element of the stream matches a predicate. + assert_eq!(sum, 6); + # + # }) } + ``` + "#] + fn fold( + self, + init: B, + f: F, + ) -> FoldFuture + where + Self: Sized, + F: FnMut(B, Self::Item) -> B, + { + FoldFuture::new(self, init, f) + } - `any()` takes a closure that returns `true` or `false`. It applies - this closure to each element of the stream, and if any of them return - `true`, then so does `any()`. If they all return `false`, it - returns `false`. + #[doc = r#" + A combinator that applies a function to every element in a stream + creating two collections from it. - `any()` is short-circuiting; in other words, it will stop processing - as soon as it finds a `true`, given that no matter what else happens, - the result will also be `true`. + # Examples - An empty stream returns `false`. + Basic usage: - # Examples + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - Basic usage: + let (even, odd): (Vec, Vec) = stream::from_iter(vec![1, 2, 3]) + .partition(|&n| n % 2 == 0).await; - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + assert_eq!(even, vec![2]); + assert_eq!(odd, vec![1, 3]); - let mut s = stream::repeat::(42).take(3); - assert!(s.any(|x| x == 42).await); - # - # }) } - ``` + # + # }) } + ``` + "#] + #[cfg(feature = "unstable")] + #[cfg_attr(feature = "docs", doc(cfg(unstable)))] + fn partition( + self, + f: F, + ) -> PartitionFuture + where + Self: Sized, + F: FnMut(&Self::Item) -> bool, + B: Default + Extend, + { + PartitionFuture::new(self, f) + } - Empty stream: + #[doc = r#" + Call a closure on each element of the stream. - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + # Examples - let mut s = stream::empty::(); - assert!(!s.any(|_| false).await); - # - # }) } - ``` - "#] - #[inline] - fn any( - &mut self, - f: F, - ) -> AnyFuture<'_, Self, F, Self::Item> - where - Self: Unpin + Sized, - F: FnMut(Self::Item) -> bool, - { - AnyFuture::new(self, f) - } + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; + use std::sync::mpsc::channel; - #[doc = r#" - Borrows an stream, rather than consuming it. + let (tx, rx) = channel(); - This is useful to allow applying stream adaptors while still retaining ownership of the original stream. + let s = stream::from_iter(vec![1usize, 2, 3]); + let sum = s.for_each(move |x| tx.clone().send(x).unwrap()).await; - # Examples + let v: Vec<_> = rx.iter().collect(); - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + assert_eq!(v, vec![1, 2, 3]); + # + # }) } + ``` + "#] + fn for_each( + self, + f: F, + ) -> ForEachFuture + where + Self: Sized, + F: FnMut(Self::Item), + { + ForEachFuture::new(self, f) + } - let a = vec![1isize, 2, 3]; + #[doc = r#" + Tests if any element of the stream matches a predicate. - let stream = stream::from_iter(a); + `any()` takes a closure that returns `true` or `false`. It applies + this closure to each element of the stream, and if any of them return + `true`, then so does `any()`. If they all return `false`, it + returns `false`. - let sum: isize = stream.take(5).sum().await; + `any()` is short-circuiting; in other words, it will stop processing + as soon as it finds a `true`, given that no matter what else happens, + the result will also be `true`. - assert_eq!(sum, 6); + An empty stream returns `false`. - // if we try to use stream again, it won't work. The following line - // gives error: use of moved value: `stream` - // assert_eq!(stream.next(), None); + # Examples - // let's try that again - let a = vec![1isize, 2, 3]; + Basic usage: - let mut stream = stream::from_iter(a); + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - // instead, we add in a .by_ref() - let sum: isize = stream.by_ref().take(2).sum().await; + let mut s = stream::repeat::(42).take(3); + assert!(s.any(|x| x == 42).await); + # + # }) } + ``` - assert_eq!(sum, 3); + Empty stream: - // now this is just fine: - assert_eq!(stream.next().await, Some(3)); - assert_eq!(stream.next().await, None); - # - # }) } - ``` - "#] - #[cfg(feature = "unstable")] - #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - fn by_ref(&mut self) -> &mut Self { - self - } + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - #[doc = r#" - A stream adaptor similar to [`fold`] that holds internal state and produces a new - stream. + let mut s = stream::empty::(); + assert!(!s.any(|_| false).await); + # + # }) } + ``` + "#] + #[inline] + fn any( + &mut self, + f: F, + ) -> AnyFuture<'_, Self, F, Self::Item> + where + Self: Unpin + Sized, + F: FnMut(Self::Item) -> bool, + { + AnyFuture::new(self, f) + } - [`fold`]: #method.fold + #[doc = r#" + Borrows an stream, rather than consuming it. - `scan()` takes two arguments: an initial value which seeds the internal state, and - a closure with two arguments, the first being a mutable reference to the internal - state and the second a stream element. The closure can assign to the internal state - to share state between iterations. + This is useful to allow applying stream adaptors while still retaining ownership of the original stream. - On iteration, the closure will be applied to each element of the stream and the - return value from the closure, an `Option`, is yielded by the stream. + # Examples - ## Examples + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + let a = vec![1isize, 2, 3]; - let s = stream::from_iter(vec![1isize, 2, 3]); - let mut s = s.scan(1, |state, x| { - *state = *state * x; - Some(-*state) - }); - - assert_eq!(s.next().await, Some(-1)); - assert_eq!(s.next().await, Some(-2)); - assert_eq!(s.next().await, Some(-6)); - assert_eq!(s.next().await, None); - # - # }) } - ``` - "#] - #[inline] - fn scan(self, initial_state: St, f: F) -> Scan - where - Self: Sized, - F: FnMut(&mut St, Self::Item) -> Option, - { - Scan::new(self, initial_state, f) - } + let stream = stream::from_iter(a); - #[doc = r#" - Combinator that `skip`s elements based on a predicate. + let sum: isize = stream.take(5).sum().await; - Takes a closure argument. It will call this closure on every element in - the stream and ignore elements until it returns `false`. + assert_eq!(sum, 6); - After `false` is returned, `SkipWhile`'s job is over and all further - elements in the strem are yielded. + // if we try to use stream again, it won't work. The following line + // gives error: use of moved value: `stream` + // assert_eq!(stream.next(), None); - ## Examples + // let's try that again + let a = vec![1isize, 2, 3]; - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + let mut stream = stream::from_iter(a); - let a = stream::from_iter(vec![-1i32, 0, 1]); - let mut s = a.skip_while(|x| x.is_negative()); - - assert_eq!(s.next().await, Some(0)); - assert_eq!(s.next().await, Some(1)); - assert_eq!(s.next().await, None); - # - # }) } - ``` - "#] - fn skip_while

(self, predicate: P) -> SkipWhile - where - Self: Sized, - P: FnMut(&Self::Item) -> bool, - { - SkipWhile::new(self, predicate) - } + // instead, we add in a .by_ref() + let sum: isize = stream.by_ref().take(2).sum().await; - #[doc = r#" - Creates a combinator that skips the first `n` elements. + assert_eq!(sum, 3); - ## Examples + // now this is just fine: + assert_eq!(stream.next().await, Some(3)); + assert_eq!(stream.next().await, None); + # + # }) } + ``` + "#] + #[cfg(feature = "unstable")] + #[cfg_attr(feature = "docs", doc(cfg(unstable)))] + fn by_ref(&mut self) -> &mut Self { + self + } - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + #[doc = r#" + A stream adaptor similar to [`fold`] that holds internal state and produces a new + stream. + + [`fold`]: #method.fold + + `scan()` takes two arguments: an initial value which seeds the internal state, and + a closure with two arguments, the first being a mutable reference to the internal + state and the second a stream element. The closure can assign to the internal state + to share state between iterations. + + On iteration, the closure will be applied to each element of the stream and the + return value from the closure, an `Option`, is yielded by the stream. + + ## Examples + + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; + + let s = stream::from_iter(vec![1isize, 2, 3]); + let mut s = s.scan(1, |state, x| { + *state = *state * x; + Some(-*state) + }); + + assert_eq!(s.next().await, Some(-1)); + assert_eq!(s.next().await, Some(-2)); + assert_eq!(s.next().await, Some(-6)); + assert_eq!(s.next().await, None); + # + # }) } + ``` + "#] + #[inline] + fn scan(self, initial_state: St, f: F) -> Scan + where + Self: Sized, + F: FnMut(&mut St, Self::Item) -> Option, + { + Scan::new(self, initial_state, f) + } - let s = stream::from_iter(vec![1u8, 2, 3]); - let mut skipped = s.skip(2); + #[doc = r#" + Combinator that `skip`s elements based on a predicate. - assert_eq!(skipped.next().await, Some(3)); - assert_eq!(skipped.next().await, None); - # - # }) } - ``` - "#] - fn skip(self, n: usize) -> Skip - where - Self: Sized, - { - Skip::new(self, n) - } + Takes a closure argument. It will call this closure on every element in + the stream and ignore elements until it returns `false`. - #[doc=r#" - Await a stream or times out after a duration of time. + After `false` is returned, `SkipWhile`'s job is over and all further + elements in the strem are yielded. - If you want to await an I/O future consider using - [`io::timeout`](../io/fn.timeout.html) instead. + ## Examples - # Examples + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - ``` - # fn main() -> std::io::Result<()> { async_std::task::block_on(async { - # - use std::time::Duration; + let a = stream::from_iter(vec![-1i32, 0, 1]); + let mut s = a.skip_while(|x| x.is_negative()); - use async_std::stream; - use async_std::prelude::*; + assert_eq!(s.next().await, Some(0)); + assert_eq!(s.next().await, Some(1)); + assert_eq!(s.next().await, None); + # + # }) } + ``` + "#] + fn skip_while

(self, predicate: P) -> SkipWhile + where + Self: Sized, + P: FnMut(&Self::Item) -> bool, + { + SkipWhile::new(self, predicate) + } - let mut s = stream::repeat(1).take(3).timeout(Duration::from_secs(1)); + #[doc = r#" + Creates a combinator that skips the first `n` elements. - while let Some(v) = s.next().await { - assert_eq!(v, Ok(1)); - } + ## Examples - // when timeout - let mut s = stream::pending::<()>().timeout(Duration::from_millis(10)); - match s.next().await { - Some(item) => assert!(item.is_err()), - None => panic!() - }; - # - # Ok(()) }) } - ``` - "#] - #[cfg(any(feature = "unstable", feature = "docs"))] - #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - fn timeout(self, dur: Duration) -> Timeout - where - Self: Stream + Sized, - { - Timeout::new(self, dur) - } + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - #[doc = r#" - A combinator that applies a function as long as it returns successfully, producing a single, final value. - Immediately returns the error when the function returns unsuccessfully. + let s = stream::from_iter(vec![1u8, 2, 3]); + let mut skipped = s.skip(2); - # Examples + assert_eq!(skipped.next().await, Some(3)); + assert_eq!(skipped.next().await, None); + # + # }) } + ``` + "#] + fn skip(self, n: usize) -> Skip + where + Self: Sized, + { + Skip::new(self, n) + } - Basic usage: + #[doc=r#" + Await a stream or times out after a duration of time. - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + If you want to await an I/O future consider using + [`io::timeout`](../io/fn.timeout.html) instead. - let mut s = stream::from_iter(vec![1usize, 2, 3]); - let sum = s.try_fold(0, |acc, v| { - if (acc+v) % 2 == 1 { - Ok(v+3) - } else { - Err("fail") - } - }).await; - - assert_eq!(sum, Err("fail")); - # - # }) } - ``` - "#] - fn try_fold( - &mut self, - init: T, - f: F, - ) -> TryFoldFuture<'_, Self, F, T> - where - Self: Unpin + Sized, - F: FnMut(B, Self::Item) -> Result, - { - TryFoldFuture::new(self, init, f) - } + # Examples - #[doc = r#" - Applies a falliable function to each element in a stream, stopping at first error and returning it. + ``` + # fn main() -> std::io::Result<()> { async_std::task::block_on(async { + # + use std::time::Duration; - # Examples + use async_std::stream; + use async_std::prelude::*; - ``` - # fn main() { async_std::task::block_on(async { - # - use std::sync::mpsc::channel; - use async_std::prelude::*; - use async_std::stream; + let mut s = stream::repeat(1).take(3).timeout(Duration::from_secs(1)); - let (tx, rx) = channel(); - - let mut s = stream::from_iter(vec![1u8, 2, 3]); - let s = s.try_for_each(|v| { - if v % 2 == 1 { - tx.clone().send(v).unwrap(); - Ok(()) - } else { - Err("even") - } - }); - - let res = s.await; - drop(tx); - let values: Vec<_> = rx.iter().collect(); - - assert_eq!(values, vec![1]); - assert_eq!(res, Err("even")); - # - # }) } - ``` - "#] - fn try_for_each( - &mut self, - f: F, - ) -> TryForEachFuture<'_, Self, F> - where - Self: Unpin + Sized, - F: FnMut(Self::Item) -> Result<(), E>, - { - TryForEachFuture::new(self, f) + while let Some(v) = s.next().await { + assert_eq!(v, Ok(1)); } - #[doc = r#" - 'Zips up' two streams into a single stream of pairs. + // when timeout + let mut s = stream::pending::<()>().timeout(Duration::from_millis(10)); + match s.next().await { + Some(item) => assert!(item.is_err()), + None => panic!() + }; + # + # Ok(()) }) } + ``` + "#] + #[cfg(any(feature = "unstable", feature = "docs"))] + #[cfg_attr(feature = "docs", doc(cfg(unstable)))] + fn timeout(self, dur: Duration) -> Timeout + where + Self: Stream + Sized, + { + Timeout::new(self, dur) + } - `zip()` returns a new stream that will iterate over two other streams, returning a - tuple where the first element comes from the first stream, and the second element - comes from the second stream. + #[doc = r#" + A combinator that applies a function as long as it returns successfully, producing a single, final value. + Immediately returns the error when the function returns unsuccessfully. - In other words, it zips two streams together, into a single one. + # Examples - If either stream returns [`None`], [`poll_next`] from the zipped stream will return - [`None`]. If the first stream returns [`None`], `zip` will short-circuit and - `poll_next` will not be called on the second stream. + Basic usage: - [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None - [`poll_next`]: #tymethod.poll_next + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - ## Examples + let mut s = stream::from_iter(vec![1usize, 2, 3]); + let sum = s.try_fold(0, |acc, v| { + if (acc+v) % 2 == 1 { + Ok(v+3) + } else { + Err("fail") + } + }).await; - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + assert_eq!(sum, Err("fail")); + # + # }) } + ``` + "#] + fn try_fold( + &mut self, + init: T, + f: F, + ) -> TryFoldFuture<'_, Self, F, T> + where + Self: Unpin + Sized, + F: FnMut(B, Self::Item) -> Result, + { + TryFoldFuture::new(self, init, f) + } - let l = stream::from_iter(vec![1u8, 2, 3]); - let r = stream::from_iter(vec![4u8, 5, 6, 7]); - let mut s = l.zip(r); - - assert_eq!(s.next().await, Some((1, 4))); - assert_eq!(s.next().await, Some((2, 5))); - assert_eq!(s.next().await, Some((3, 6))); - assert_eq!(s.next().await, None); - # - # }) } - ``` - "#] - #[inline] - fn zip(self, other: U) -> Zip - where - Self: Sized, - U: Stream, - { - Zip::new(self, other) - } + #[doc = r#" + Applies a falliable function to each element in a stream, stopping at first error and returning it. + + # Examples + + ``` + # fn main() { async_std::task::block_on(async { + # + use std::sync::mpsc::channel; + use async_std::prelude::*; + use async_std::stream; + + let (tx, rx) = channel(); + + let mut s = stream::from_iter(vec![1u8, 2, 3]); + let s = s.try_for_each(|v| { + if v % 2 == 1 { + tx.clone().send(v).unwrap(); + Ok(()) + } else { + Err("even") + } + }); - #[doc = r#" - Converts an stream of pairs into a pair of containers. + let res = s.await; + drop(tx); + let values: Vec<_> = rx.iter().collect(); - `unzip()` consumes an entire stream of pairs, producing two collections: one from the left elements of the pairs, and one from the right elements. + assert_eq!(values, vec![1]); + assert_eq!(res, Err("even")); + # + # }) } + ``` + "#] + fn try_for_each( + &mut self, + f: F, + ) -> TryForEachFuture<'_, Self, F> + where + Self: Unpin + Sized, + F: FnMut(Self::Item) -> Result<(), E>, + { + TryForEachFuture::new(self, f) + } - This function is, in some sense, the opposite of [`zip`]. + #[doc = r#" + 'Zips up' two streams into a single stream of pairs. - [`zip`]: trait.Stream.html#method.zip + `zip()` returns a new stream that will iterate over two other streams, returning a + tuple where the first element comes from the first stream, and the second element + comes from the second stream. - # Example + In other words, it zips two streams together, into a single one. - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + If either stream returns [`None`], [`poll_next`] from the zipped stream will return + [`None`]. If the first stream returns [`None`], `zip` will short-circuit and + `poll_next` will not be called on the second stream. - let s = stream::from_iter(vec![(1,2), (3,4)]); + [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None + [`poll_next`]: #tymethod.poll_next - let (left, right): (Vec<_>, Vec<_>) = s.unzip().await; + ## Examples - assert_eq!(left, [1, 3]); - assert_eq!(right, [2, 4]); - # - # }) } - ``` - "#] - #[cfg(feature = "unstable")] - #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - fn unzip(self) -> UnzipFuture - where - FromA: Default + Extend, - FromB: Default + Extend, - Self: Stream + Sized, - { - UnzipFuture::new(self) - } + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - #[doc = r#" - Transforms a stream into a collection. + let l = stream::from_iter(vec![1u8, 2, 3]); + let r = stream::from_iter(vec![4u8, 5, 6, 7]); + let mut s = l.zip(r); - `collect()` can take anything streamable, and turn it into a relevant - collection. This is one of the more powerful methods in the async - standard library, used in a variety of contexts. + assert_eq!(s.next().await, Some((1, 4))); + assert_eq!(s.next().await, Some((2, 5))); + assert_eq!(s.next().await, Some((3, 6))); + assert_eq!(s.next().await, None); + # + # }) } + ``` + "#] + #[inline] + fn zip(self, other: U) -> Zip + where + Self: Sized, + U: Stream, + { + Zip::new(self, other) + } - The most basic pattern in which `collect()` is used is to turn one - collection into another. You take a collection, call [`into_stream`] on it, - do a bunch of transformations, and then `collect()` at the end. + #[doc = r#" + Converts an stream of pairs into a pair of containers. - Because `collect()` is so general, it can cause problems with type - inference. As such, `collect()` is one of the few times you'll see - the syntax affectionately known as the 'turbofish': `::<>`. This - helps the inference algorithm understand specifically which collection - you're trying to collect into. + `unzip()` consumes an entire stream of pairs, producing two collections: one from the left elements of the pairs, and one from the right elements. - # Examples + This function is, in some sense, the opposite of [`zip`]. - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + [`zip`]: trait.Stream.html#method.zip - let s = stream::repeat(9u8).take(3); - let buf: Vec = s.collect().await; - - assert_eq!(buf, vec![9; 3]); - - // You can also collect streams of Result values - // into any collection that implements FromStream - let s = stream::repeat(Ok(9)).take(3); - // We are using Vec here, but other collections - // are supported as well - let buf: Result, ()> = s.collect().await; - - assert_eq!(buf, Ok(vec![9; 3])); - - // The stream will stop on the first Err and - // return that instead - let s = stream::repeat(Err(5)).take(3); - let buf: Result, u8> = s.collect().await; - - assert_eq!(buf, Err(5)); - # - # }) } - ``` - - [`into_stream`]: trait.IntoStream.html#tymethod.into_stream - "#] - #[cfg(feature = "unstable")] - #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - fn collect<'a, B>( - self, - ) -> Pin + 'a + Send>> - where - Self: Sized + 'a + Send, - B: FromStream, - Self::Item: Send, - { - FromStream::from_stream(self) - } + # Example - #[doc = r#" - Combines multiple streams into a single stream of all their outputs. + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - Items are yielded as soon as they're received, and the stream continues yield until - both streams have been exhausted. The output ordering between streams is not guaranteed. + let s = stream::from_iter(vec![(1,2), (3,4)]); - # Examples + let (left, right): (Vec<_>, Vec<_>) = s.unzip().await; - ``` - # async_std::task::block_on(async { - use async_std::prelude::*; - use async_std::stream::{self, FromStream}; - - let a = stream::once(1u8); - let b = stream::once(2u8); - let c = stream::once(3u8); - - let s = a.merge(b).merge(c); - let mut lst = Vec::from_stream(s).await; - - lst.sort_unstable(); - assert_eq!(&lst, &[1u8, 2u8, 3u8]); - # }); - ``` - "#] - #[cfg(feature = "unstable")] - #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - fn merge(self, other: U) -> Merge - where - Self: Sized, - U: Stream + Sized, - { - Merge::new(self, other) - } + assert_eq!(left, [1, 3]); + assert_eq!(right, [2, 4]); + # + # }) } + ``` + "#] + #[cfg(feature = "unstable")] + #[cfg_attr(feature = "docs", doc(cfg(unstable)))] + fn unzip(self) -> UnzipFuture + where + FromA: Default + Extend, + FromB: Default + Extend, + Self: Stream + Sized, + { + UnzipFuture::new(self) + } - #[doc = r#" - Lexicographically compares the elements of this `Stream` with those - of another. + #[doc = r#" + Transforms a stream into a collection. - # Examples + `collect()` can take anything streamable, and turn it into a relevant + collection. This is one of the more powerful methods in the async + standard library, used in a variety of contexts. - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + The most basic pattern in which `collect()` is used is to turn one + collection into another. You take a collection, call [`into_stream`] on it, + do a bunch of transformations, and then `collect()` at the end. - use std::cmp::Ordering; - - let s1 = stream::from_iter(vec![1]); - let s2 = stream::from_iter(vec![1, 2]); - let s3 = stream::from_iter(vec![1, 2, 3]); - let s4 = stream::from_iter(vec![1, 2, 4]); - assert_eq!(s1.clone().partial_cmp(s1.clone()).await, Some(Ordering::Equal)); - assert_eq!(s1.clone().partial_cmp(s2.clone()).await, Some(Ordering::Less)); - assert_eq!(s2.clone().partial_cmp(s1.clone()).await, Some(Ordering::Greater)); - assert_eq!(s3.clone().partial_cmp(s4.clone()).await, Some(Ordering::Less)); - assert_eq!(s4.clone().partial_cmp(s3.clone()).await, Some(Ordering::Greater)); - # - # }) } - ``` - "#] - fn partial_cmp( - self, - other: S - ) -> PartialCmpFuture - where - Self: Sized + Stream, - S: Stream, - ::Item: PartialOrd, - { - PartialCmpFuture::new(self, other) - } + Because `collect()` is so general, it can cause problems with type + inference. As such, `collect()` is one of the few times you'll see + the syntax affectionately known as the 'turbofish': `::<>`. This + helps the inference algorithm understand specifically which collection + you're trying to collect into. - #[doc = r#" - Searches for an element in a Stream that satisfies a predicate, returning - its index. + # Examples - # Examples + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + let s = stream::repeat(9u8).take(3); + let buf: Vec = s.collect().await; - let s = stream::from_iter(vec![1usize, 2, 3]); - let res = s.clone().position(|x| x == 1).await; - assert_eq!(res, Some(0)); - - let res = s.clone().position(|x| x == 2).await; - assert_eq!(res, Some(1)); - - let res = s.clone().position(|x| x == 3).await; - assert_eq!(res, Some(2)); - - let res = s.clone().position(|x| x == 4).await; - assert_eq!(res, None); - # - # }) } - ``` - "#] - fn position

( - &mut self, - predicate: P, - ) -> PositionFuture<'_, Self, P> - where - Self: Unpin + Sized, - P: FnMut(Self::Item) -> bool, - { - PositionFuture::new(self, predicate) - } + assert_eq!(buf, vec![9; 3]); - #[doc = r#" - Lexicographically compares the elements of this `Stream` with those - of another using 'Ord'. + // You can also collect streams of Result values + // into any collection that implements FromStream + let s = stream::repeat(Ok(9)).take(3); + // We are using Vec here, but other collections + // are supported as well + let buf: Result, ()> = s.collect().await; - # Examples + assert_eq!(buf, Ok(vec![9; 3])); - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; - use std::cmp::Ordering; - - let s1 = stream::from_iter(vec![1]); - let s2 = stream::from_iter(vec![1, 2]); - let s3 = stream::from_iter(vec![1, 2, 3]); - let s4 = stream::from_iter(vec![1, 2, 4]); - - assert_eq!(s1.clone().cmp(s1.clone()).await, Ordering::Equal); - assert_eq!(s1.clone().cmp(s2.clone()).await, Ordering::Less); - assert_eq!(s2.clone().cmp(s1.clone()).await, Ordering::Greater); - assert_eq!(s3.clone().cmp(s4.clone()).await, Ordering::Less); - assert_eq!(s4.clone().cmp(s3.clone()).await, Ordering::Greater); - # - # }) } - ``` - "#] - fn cmp( - self, - other: S - ) -> CmpFuture - where - Self: Sized + Stream, - S: Stream, - ::Item: Ord - { - CmpFuture::new(self, other) - } + // The stream will stop on the first Err and + // return that instead + let s = stream::repeat(Err(5)).take(3); + let buf: Result, u8> = s.collect().await; - #[doc = r#" - Counts the number of elements in the stream. + assert_eq!(buf, Err(5)); + # + # }) } + ``` - # Examples + [`into_stream`]: trait.IntoStream.html#tymethod.into_stream + "#] + #[cfg(feature = "unstable")] + #[cfg_attr(feature = "docs", doc(cfg(unstable)))] + fn collect<'a, B>( + self, + ) -> Pin + 'a + Send>> + where + Self: Sized + 'a + Send, + B: FromStream, + Self::Item: Send, + { + FromStream::from_stream(self) + } - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + #[doc = r#" + Combines multiple streams into a single stream of all their outputs. - let s1 = stream::from_iter(vec![0]); - let s2 = stream::from_iter(vec![1, 2, 3]); - - assert_eq!(s1.count().await, 1); - assert_eq!(s2.count().await, 3); - # - # }) } - ``` - "#] - #[cfg(feature = "unstable")] - #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - fn count(self) -> CountFuture - where - Self: Sized, - { - CountFuture::new(self) - } + Items are yielded as soon as they're received, and the stream continues yield until + both streams have been exhausted. The output ordering between streams is not guaranteed. - #[doc = r#" - Determines if the elements of this `Stream` are lexicographically - not equal to those of another. + # Examples - # Examples + ``` + # async_std::task::block_on(async { + use async_std::prelude::*; + use async_std::stream::{self, FromStream}; - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + let a = stream::once(1u8); + let b = stream::once(2u8); + let c = stream::once(3u8); - let single = stream::from_iter(vec![1usize]); - let single_ne = stream::from_iter(vec![10usize]); - let multi = stream::from_iter(vec![1usize,2]); - let multi_ne = stream::from_iter(vec![1usize,5]); - - assert_eq!(single.clone().ne(single.clone()).await, false); - assert_eq!(single_ne.clone().ne(single.clone()).await, true); - assert_eq!(multi.clone().ne(single_ne.clone()).await, true); - assert_eq!(multi_ne.clone().ne(multi.clone()).await, true); - # - # }) } - ``` - "#] - fn ne( - self, - other: S - ) -> NeFuture - where - Self: Sized, - S: Sized + Stream, - ::Item: PartialEq, - { - NeFuture::new(self, other) - } + let s = a.merge(b).merge(c); + let mut lst = Vec::from_stream(s).await; - #[doc = r#" - Determines if the elements of this `Stream` are lexicographically - greater than or equal to those of another. + lst.sort_unstable(); + assert_eq!(&lst, &[1u8, 2u8, 3u8]); + # }); + ``` + "#] + #[cfg(feature = "unstable")] + #[cfg_attr(feature = "docs", doc(cfg(unstable)))] + fn merge(self, other: U) -> Merge + where + Self: Sized, + U: Stream + Sized, + { + Merge::new(self, other) + } - # Examples + #[doc = r#" + Lexicographically compares the elements of this `Stream` with those + of another. + + # Examples + + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; + + use std::cmp::Ordering; + + let s1 = stream::from_iter(vec![1]); + let s2 = stream::from_iter(vec![1, 2]); + let s3 = stream::from_iter(vec![1, 2, 3]); + let s4 = stream::from_iter(vec![1, 2, 4]); + assert_eq!(s1.clone().partial_cmp(s1.clone()).await, Some(Ordering::Equal)); + assert_eq!(s1.clone().partial_cmp(s2.clone()).await, Some(Ordering::Less)); + assert_eq!(s2.clone().partial_cmp(s1.clone()).await, Some(Ordering::Greater)); + assert_eq!(s3.clone().partial_cmp(s4.clone()).await, Some(Ordering::Less)); + assert_eq!(s4.clone().partial_cmp(s3.clone()).await, Some(Ordering::Greater)); + # + # }) } + ``` + "#] + fn partial_cmp( + self, + other: S + ) -> PartialCmpFuture + where + Self: Sized + Stream, + S: Stream, + ::Item: PartialOrd, + { + PartialCmpFuture::new(self, other) + } - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + #[doc = r#" + Searches for an element in a Stream that satisfies a predicate, returning + its index. - let single = stream::from_iter(vec![1]); - let single_gt = stream::from_iter(vec![10]); - let multi = stream::from_iter(vec![1,2]); - let multi_gt = stream::from_iter(vec![1,5]); - - assert_eq!(single.clone().ge(single.clone()).await, true); - assert_eq!(single_gt.clone().ge(single.clone()).await, true); - assert_eq!(multi.clone().ge(single_gt.clone()).await, false); - assert_eq!(multi_gt.clone().ge(multi.clone()).await, true); - # - # }) } - ``` - "#] - fn ge( - self, - other: S - ) -> GeFuture - where - Self: Sized + Stream, - S: Stream, - ::Item: PartialOrd, - { - GeFuture::new(self, other) - } + # Examples - #[doc = r#" - Determines if the elements of this `Stream` are lexicographically - equal to those of another. + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - # Examples + let s = stream::from_iter(vec![1usize, 2, 3]); + let res = s.clone().position(|x| x == 1).await; + assert_eq!(res, Some(0)); - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + let res = s.clone().position(|x| x == 2).await; + assert_eq!(res, Some(1)); - let single = stream::from_iter(vec![1]); - let single_eq = stream::from_iter(vec![10]); - let multi = stream::from_iter(vec![1,2]); - let multi_eq = stream::from_iter(vec![1,5]); - - assert_eq!(single.clone().eq(single.clone()).await, true); - assert_eq!(single_eq.clone().eq(single.clone()).await, false); - assert_eq!(multi.clone().eq(single_eq.clone()).await, false); - assert_eq!(multi_eq.clone().eq(multi.clone()).await, false); - # - # }) } - ``` - "#] - fn eq( - self, - other: S - ) -> EqFuture - where - Self: Sized + Stream, - S: Sized + Stream, - ::Item: PartialEq, - { - EqFuture::new(self, other) - } + let res = s.clone().position(|x| x == 3).await; + assert_eq!(res, Some(2)); - #[doc = r#" - Determines if the elements of this `Stream` are lexicographically - greater than those of another. + let res = s.clone().position(|x| x == 4).await; + assert_eq!(res, None); + # + # }) } + ``` + "#] + fn position

( + &mut self, + predicate: P, + ) -> PositionFuture<'_, Self, P> + where + Self: Unpin + Sized, + P: FnMut(Self::Item) -> bool, + { + PositionFuture::new(self, predicate) + } - # Examples + #[doc = r#" + Lexicographically compares the elements of this `Stream` with those + of another using 'Ord'. + + # Examples + + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; + use std::cmp::Ordering; + + let s1 = stream::from_iter(vec![1]); + let s2 = stream::from_iter(vec![1, 2]); + let s3 = stream::from_iter(vec![1, 2, 3]); + let s4 = stream::from_iter(vec![1, 2, 4]); + + assert_eq!(s1.clone().cmp(s1.clone()).await, Ordering::Equal); + assert_eq!(s1.clone().cmp(s2.clone()).await, Ordering::Less); + assert_eq!(s2.clone().cmp(s1.clone()).await, Ordering::Greater); + assert_eq!(s3.clone().cmp(s4.clone()).await, Ordering::Less); + assert_eq!(s4.clone().cmp(s3.clone()).await, Ordering::Greater); + # + # }) } + ``` + "#] + fn cmp( + self, + other: S + ) -> CmpFuture + where + Self: Sized + Stream, + S: Stream, + ::Item: Ord + { + CmpFuture::new(self, other) + } - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + #[doc = r#" + Counts the number of elements in the stream. - let single = stream::from_iter(vec![1]); - let single_gt = stream::from_iter(vec![10]); - let multi = stream::from_iter(vec![1,2]); - let multi_gt = stream::from_iter(vec![1,5]); - - assert_eq!(single.clone().gt(single.clone()).await, false); - assert_eq!(single_gt.clone().gt(single.clone()).await, true); - assert_eq!(multi.clone().gt(single_gt.clone()).await, false); - assert_eq!(multi_gt.clone().gt(multi.clone()).await, true); - # - # }) } - ``` - "#] - fn gt( - self, - other: S - ) -> GtFuture - where - Self: Sized + Stream, - S: Stream, - ::Item: PartialOrd, - { - GtFuture::new(self, other) - } + # Examples - #[doc = r#" - Determines if the elements of this `Stream` are lexicographically - less or equal to those of another. + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - # Examples + let s1 = stream::from_iter(vec![0]); + let s2 = stream::from_iter(vec![1, 2, 3]); - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + assert_eq!(s1.count().await, 1); + assert_eq!(s2.count().await, 3); + # + # }) } + ``` + "#] + #[cfg(feature = "unstable")] + #[cfg_attr(feature = "docs", doc(cfg(unstable)))] + fn count(self) -> CountFuture + where + Self: Sized, + { + CountFuture::new(self) + } - let single = stream::from_iter(vec![1]); - let single_gt = stream::from_iter(vec![10]); - let multi = stream::from_iter(vec![1,2]); - let multi_gt = stream::from_iter(vec![1,5]); - - assert_eq!(single.clone().le(single.clone()).await, true); - assert_eq!(single.clone().le(single_gt.clone()).await, true); - assert_eq!(multi.clone().le(single_gt.clone()).await, true); - assert_eq!(multi_gt.clone().le(multi.clone()).await, false); - # - # }) } - ``` - "#] - fn le( - self, - other: S - ) -> LeFuture - where - Self: Sized + Stream, - S: Stream, - ::Item: PartialOrd, - { - LeFuture::new(self, other) - } + #[doc = r#" + Determines if the elements of this `Stream` are lexicographically + not equal to those of another. + + # Examples + + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; + + let single = stream::from_iter(vec![1usize]); + let single_ne = stream::from_iter(vec![10usize]); + let multi = stream::from_iter(vec![1usize,2]); + let multi_ne = stream::from_iter(vec![1usize,5]); + + assert_eq!(single.clone().ne(single.clone()).await, false); + assert_eq!(single_ne.clone().ne(single.clone()).await, true); + assert_eq!(multi.clone().ne(single_ne.clone()).await, true); + assert_eq!(multi_ne.clone().ne(multi.clone()).await, true); + # + # }) } + ``` + "#] + fn ne( + self, + other: S + ) -> NeFuture + where + Self: Sized, + S: Sized + Stream, + ::Item: PartialEq, + { + NeFuture::new(self, other) + } - #[doc = r#" - Determines if the elements of this `Stream` are lexicographically - less than those of another. + #[doc = r#" + Determines if the elements of this `Stream` are lexicographically + greater than or equal to those of another. + + # Examples + + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; + + let single = stream::from_iter(vec![1]); + let single_gt = stream::from_iter(vec![10]); + let multi = stream::from_iter(vec![1,2]); + let multi_gt = stream::from_iter(vec![1,5]); + + assert_eq!(single.clone().ge(single.clone()).await, true); + assert_eq!(single_gt.clone().ge(single.clone()).await, true); + assert_eq!(multi.clone().ge(single_gt.clone()).await, false); + assert_eq!(multi_gt.clone().ge(multi.clone()).await, true); + # + # }) } + ``` + "#] + fn ge( + self, + other: S + ) -> GeFuture + where + Self: Sized + Stream, + S: Stream, + ::Item: PartialOrd, + { + GeFuture::new(self, other) + } - # Examples + #[doc = r#" + Determines if the elements of this `Stream` are lexicographically + equal to those of another. + + # Examples + + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; + + let single = stream::from_iter(vec![1]); + let single_eq = stream::from_iter(vec![10]); + let multi = stream::from_iter(vec![1,2]); + let multi_eq = stream::from_iter(vec![1,5]); + + assert_eq!(single.clone().eq(single.clone()).await, true); + assert_eq!(single_eq.clone().eq(single.clone()).await, false); + assert_eq!(multi.clone().eq(single_eq.clone()).await, false); + assert_eq!(multi_eq.clone().eq(multi.clone()).await, false); + # + # }) } + ``` + "#] + fn eq( + self, + other: S + ) -> EqFuture + where + Self: Sized + Stream, + S: Sized + Stream, + ::Item: PartialEq, + { + EqFuture::new(self, other) + } - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + #[doc = r#" + Determines if the elements of this `Stream` are lexicographically + greater than those of another. + + # Examples + + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; + + let single = stream::from_iter(vec![1]); + let single_gt = stream::from_iter(vec![10]); + let multi = stream::from_iter(vec![1,2]); + let multi_gt = stream::from_iter(vec![1,5]); + + assert_eq!(single.clone().gt(single.clone()).await, false); + assert_eq!(single_gt.clone().gt(single.clone()).await, true); + assert_eq!(multi.clone().gt(single_gt.clone()).await, false); + assert_eq!(multi_gt.clone().gt(multi.clone()).await, true); + # + # }) } + ``` + "#] + fn gt( + self, + other: S + ) -> GtFuture + where + Self: Sized + Stream, + S: Stream, + ::Item: PartialOrd, + { + GtFuture::new(self, other) + } - let single = stream::from_iter(vec![1]); - let single_gt = stream::from_iter(vec![10]); - let multi = stream::from_iter(vec![1,2]); - let multi_gt = stream::from_iter(vec![1,5]); - - assert_eq!(single.clone().lt(single.clone()).await, false); - assert_eq!(single.clone().lt(single_gt.clone()).await, true); - assert_eq!(multi.clone().lt(single_gt.clone()).await, true); - assert_eq!(multi_gt.clone().lt(multi.clone()).await, false); - # - # }) } - ``` - "#] - fn lt( - self, - other: S - ) -> LtFuture - where - Self: Sized + Stream, - S: Stream, - ::Item: PartialOrd, - { - LtFuture::new(self, other) - } + #[doc = r#" + Determines if the elements of this `Stream` are lexicographically + less or equal to those of another. + + # Examples + + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; + + let single = stream::from_iter(vec![1]); + let single_gt = stream::from_iter(vec![10]); + let multi = stream::from_iter(vec![1,2]); + let multi_gt = stream::from_iter(vec![1,5]); + + assert_eq!(single.clone().le(single.clone()).await, true); + assert_eq!(single.clone().le(single_gt.clone()).await, true); + assert_eq!(multi.clone().le(single_gt.clone()).await, true); + assert_eq!(multi_gt.clone().le(multi.clone()).await, false); + # + # }) } + ``` + "#] + fn le( + self, + other: S + ) -> LeFuture + where + Self: Sized + Stream, + S: Stream, + ::Item: PartialOrd, + { + LeFuture::new(self, other) + } - #[doc = r#" - Sums the elements of a stream. + #[doc = r#" + Determines if the elements of this `Stream` are lexicographically + less than those of another. + + # Examples + + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; + + let single = stream::from_iter(vec![1]); + let single_gt = stream::from_iter(vec![10]); + let multi = stream::from_iter(vec![1,2]); + let multi_gt = stream::from_iter(vec![1,5]); + + assert_eq!(single.clone().lt(single.clone()).await, false); + assert_eq!(single.clone().lt(single_gt.clone()).await, true); + assert_eq!(multi.clone().lt(single_gt.clone()).await, true); + assert_eq!(multi_gt.clone().lt(multi.clone()).await, false); + # + # }) } + ``` + "#] + fn lt( + self, + other: S + ) -> LtFuture + where + Self: Sized + Stream, + S: Stream, + ::Item: PartialOrd, + { + LtFuture::new(self, other) + } - Takes each element, adds them together, and returns the result. + #[doc = r#" + Sums the elements of a stream. - An empty streams returns the zero value of the type. + Takes each element, adds them together, and returns the result. - # Panics + An empty streams returns the zero value of the type. - When calling `sum()` and a primitive integer type is being returned, this - method will panic if the computation overflows and debug assertions are - enabled. + # Panics - # Examples + When calling `sum()` and a primitive integer type is being returned, this + method will panic if the computation overflows and debug assertions are + enabled. - Basic usage: + # Examples - ``` - # fn main() { async_std::task::block_on(async { - # - use async_std::prelude::*; - use async_std::stream; + Basic usage: - let s = stream::from_iter(vec![0u8, 1, 2, 3, 4]); - let sum: u8 = s.sum().await; - - assert_eq!(sum, 10); - # - # }) } - ``` - "#] - #[cfg(feature = "unstable")] - #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - fn sum<'a, S>( - self, - ) -> Pin + 'a>> - where - Self: Sized + Stream + 'a, - S: Sum, - { - Sum::sum(self) - } + ``` + # fn main() { async_std::task::block_on(async { + # + use async_std::prelude::*; + use async_std::stream; - #[doc = r#" - Multiplies all elements of the stream. + let s = stream::from_iter(vec![0u8, 1, 2, 3, 4]); + let sum: u8 = s.sum().await; - An empty stream returns the one value of the type. + assert_eq!(sum, 10); + # + # }) } + ``` + "#] + #[cfg(feature = "unstable")] + #[cfg_attr(feature = "docs", doc(cfg(unstable)))] + fn sum<'a, S>( + self, + ) -> Pin + 'a>> + where + Self: Sized + Stream + 'a, + S: Sum, + { + Sum::sum(self) + } - # Panics + #[doc = r#" + Multiplies all elements of the stream. - When calling `product()` and a primitive integer type is being returned, - method will panic if the computation overflows and debug assertions are - enabled. + An empty stream returns the one value of the type. - # Examples + # Panics - This example calculates the factorial of n (i.e. the product of the numbers from 1 to - n, inclusive): + When calling `product()` and a primitive integer type is being returned, + method will panic if the computation overflows and debug assertions are + enabled. - ``` - # fn main() { async_std::task::block_on(async { - # - async fn factorial(n: u32) -> u32 { - use async_std::prelude::*; - use async_std::stream; + # Examples - let s = stream::from_iter(1..=n); - s.product().await - } + This example calculates the factorial of n (i.e. the product of the numbers from 1 to + n, inclusive): - assert_eq!(factorial(0).await, 1); - assert_eq!(factorial(1).await, 1); - assert_eq!(factorial(5).await, 120); - # - # }) } - ``` - "#] - #[cfg(feature = "unstable")] - #[cfg_attr(feature = "docs", doc(cfg(unstable)))] - fn product<'a, P>( - self, - ) -> Pin + 'a>> - where - Self: Sized + Stream + 'a, - P: Product, - { - Product::product(self) + ``` + # fn main() { async_std::task::block_on(async { + # + async fn factorial(n: u32) -> u32 { + use async_std::prelude::*; + use async_std::stream; + + let s = stream::from_iter(1..=n); + s.product().await } + + assert_eq!(factorial(0).await, 1); + assert_eq!(factorial(1).await, 1); + assert_eq!(factorial(5).await, 120); + # + # }) } + ``` + "#] + #[cfg(feature = "unstable")] + #[cfg_attr(feature = "docs", doc(cfg(unstable)))] + fn product<'a, P>( + self, + ) -> Pin + 'a>> + where + Self: Sized + Stream + 'a, + P: Product, + { + Product::product(self) } +} impl StreamExt for T {} From cca0f3e3212e62427cb972a21bf8a46478166315 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 15 Mar 2022 09:53:28 +1100 Subject: [PATCH 11/11] Use the default `recursion_limit`. Now that `extension_trait!` is gone, an increased limit isn't necessary. --- src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index ebbb3965..669d05a7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -282,7 +282,6 @@ #![doc(test(attr(deny(rust_2018_idioms, warnings))))] #![doc(test(attr(allow(unused_extern_crates, unused_variables))))] #![doc(html_logo_url = "https://async.rs/images/logo--hero.svg")] -#![recursion_limit = "2048"] extern crate alloc;