@@ -40,8 +40,12 @@ use min_by::MinByFuture;
4040use next:: NextFuture ;
4141use nth:: NthFuture ;
4242
43+ use super :: from_stream:: FromStream ;
44+ use crate :: future:: Future ;
45+ use crate :: task:: { Context , Poll } ;
4346use std:: cmp:: Ordering ;
4447use std:: marker:: PhantomData ;
48+ use std:: pin:: Pin ;
4549
4650use cfg_if:: cfg_if;
4751
@@ -67,6 +71,21 @@ cfg_if! {
6771 }
6872}
6973
74+ cfg_if ! {
75+ if #[ cfg( feature = "docs" ) ] {
76+ #[ doc( hidden) ]
77+ pub struct DynFuture <' a, T >( std:: marker:: PhantomData <& ' a T >) ;
78+
79+ macro_rules! dyn_ret {
80+ ( $a: lifetime, $o: ty) => ( DynFuture <$a, $o>) ;
81+ }
82+ } else {
83+ macro_rules! dyn_ret {
84+ ( $a: lifetime, $o: ty) => ( Pin <Box <dyn core:: future:: Future <Output = $o> + ' a>>)
85+ }
86+ }
87+ }
88+
7089/// An asynchronous stream of values.
7190///
7291/// This trait is an async version of [`std::iter::Iterator`].
@@ -361,7 +380,6 @@ pub trait Stream {
361380 ///
362381 /// Basic usage:
363382 ///
364- /// ```
365383 /// # fn main() { async_std::task::block_on(async {
366384 /// #
367385 /// use async_std::prelude::*;
@@ -400,6 +418,48 @@ pub trait Stream {
400418 f,
401419 }
402420 }
421+
422+ /// Transforms a stream into a collection.
423+ ///
424+ /// `collect()` can take anything streamable, and turn it into a relevant
425+ /// collection. This is one of the more powerful methods in the async
426+ /// standard library, used in a variety of contexts.
427+ ///
428+ /// The most basic pattern in which `collect()` is used is to turn one
429+ /// collection into another. You take a collection, call [`stream`] on it,
430+ /// do a bunch of transformations, and then `collect()` at the end.
431+ ///
432+ /// Because `collect()` is so general, it can cause problems with type
433+ /// inference. As such, `collect()` is one of the few times you'll see
434+ /// the syntax affectionately known as the 'turbofish': `::<>`. This
435+ /// helps the inference algorithm understand specifically which collection
436+ /// you're trying to collect into.
437+ ///
438+ /// # Examples
439+ ///
440+ /// ```
441+ /// # fn main() { async_std::task::block_on(async {
442+ /// #
443+ /// use async_std::prelude::*;
444+ /// use async_std::stream;
445+ ///
446+ /// let s = stream::repeat(9u8).take(3);
447+ /// let buf: Vec<u8> = s.collect().await;
448+ ///
449+ /// assert_eq!(buf, vec![9; 3]);
450+ /// #
451+ /// # }) }
452+ /// ```
453+ ///
454+ /// [`stream`]: trait.Stream.html#tymethod.next
455+ #[ must_use = "if you really need to exhaust the iterator, consider `.for_each(drop)` instead (TODO)" ]
456+ fn collect < ' a , B > ( self ) -> dyn_ret ! ( ' a, B )
457+ where
458+ Self : futures_core:: stream:: Stream + Sized + ' a ,
459+ B : FromStream < <Self as futures_core:: stream:: Stream >:: Item > ,
460+ {
461+ FromStream :: from_stream ( self )
462+ }
403463}
404464
405465impl < T : futures_core:: stream:: Stream + Unpin + ?Sized > Stream for T {
0 commit comments