From e9d9c8d255a02133c239280b25b1063a2b621676 Mon Sep 17 00:00:00 2001 From: Nell Shamrell Date: Fri, 29 May 2020 16:51:30 -0700 Subject: [PATCH 01/10] wip Signed-off-by: Nell Shamrell --- rfc-drafts/stream.md | 46 +++++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/rfc-drafts/stream.md b/rfc-drafts/stream.md index b1dba8f8..7ade9462 100644 --- a/rfc-drafts/stream.md +++ b/rfc-drafts/stream.md @@ -13,21 +13,27 @@ standard library. # Motivation [motivation]: #motivation -* Why include stream trait in the std library at all? - * Streams are a core async abstraction - * we want to enable portable libraries that produce/consume streams without being tied to particular executors - * examples of crates that are consuming streams? - * [async-h1](https://docs.rs/async-h1)'s server implementation takes `TcpStream` instances produced by a `TcpListener` in a loop. - * examples of crates that are producing streams? - * [async-sse](https://docs.rs/async-sse/) parses incoming buffers into a stream of messages. - * people can do this today using futures crate, but the stability guarantees are less clear - * e.g., if tokio wishes to declare a [5 year stability period](http://smallcultfollowing.com/babysteps/blog/2020/02/11/async-interview-6-eliza-weisman/#communicating-stability), having something in std means there are no concerns about trait changing during that time ([citation](http://smallcultfollowing.com/babysteps/blog/2019/12/23/async-interview-3-carl-lerche/#what-should-we-do-next-stabilize-stream)) - * We eventually want dedicated syntax for working with streams, which will require a shared trait - * Producing streams - * Consuming streams -* Why is the stream trait defined how it is? - * It is the "pollable iterator" - * dyn compatibility +Streams are a core async abstraction. We want to enable portable libraries that produce/consume streams without being tied to a particular executor. + +People can do this currently using the [futures](https://crates.io/crates/futures) crate, but stability guarantees are clearer when traits are added to the standard library than when they exist in a separate crate. For example, if [Tokio](https://tokio.rs/) wishes to declare a [5 year stability period](http://smallcultfollowing.com/babysteps/blog/2020/02/11/async-interview-6-eliza-weisman/#communicating-stability), having the stream trait in std means there are no concerns about trait changing during that time ([citation](http://smallcultfollowing.com/babysteps/blog/2019/12/23/async-interview-3-carl-lerche/#what-should-we-do-next-stabilize-stream)). + +## Examples of crates that are consuming streams + +### async-h1 + +* [async-h1](https://docs.rs/async-h1)'s server implementation takes `TcpStream` instances produced by a `TcpListener` in a loop. + +### async-sse + +* [async-sse](https://docs.rs/async-sse/) parses incoming buffers into a stream of messages. + +## Why a shared trait? + +We eventually want dedicated syntax for working with streams, which will require a shared trait. This includes a trait for producing streams and a trait for consuming streams. + +## Why is the stream trait defined how it is? +* It is the "pollable iterator" +* dyn compatibility # Guide-level explanation [guide-level-explanation]: #guide-level-explanation @@ -163,7 +169,15 @@ Why should we *not* do this? [prior-art]: #prior-art Discuss prior art, both the good and the bad, in relation to this proposal. -A few examples of what this can include are: + +The best example of prior art in Rust is the [futures](https://crates.io/crates/futures) crate. + +* Ruby - https://github.com/socketry/async-io +* Javascript https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator +* more Javascript https://javascript.info/async-iterators-generators +* Dart https://dart.dev/tutorials/language/streams + + - For language, library, cargo, tools, and compiler proposals: Does this feature exist in other programming languages and what experience have their community had? - For community proposals: Is this done by some other community and what were their experiences with it? From 229f2dcf608d63c075f5377147580ffcc0a87306 Mon Sep 17 00:00:00 2001 From: Nell Shamrell Date: Mon, 1 Jun 2020 14:01:54 -0700 Subject: [PATCH 02/10] adds more notes Signed-off-by: Nell Shamrell --- rfc-drafts/stream.md | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/rfc-drafts/stream.md b/rfc-drafts/stream.md index 7ade9462..968bf0bd 100644 --- a/rfc-drafts/stream.md +++ b/rfc-drafts/stream.md @@ -15,7 +15,7 @@ standard library. Streams are a core async abstraction. We want to enable portable libraries that produce/consume streams without being tied to a particular executor. -People can do this currently using the [futures](https://crates.io/crates/futures) crate, but stability guarantees are clearer when traits are added to the standard library than when they exist in a separate crate. For example, if [Tokio](https://tokio.rs/) wishes to declare a [5 year stability period](http://smallcultfollowing.com/babysteps/blog/2020/02/11/async-interview-6-eliza-weisman/#communicating-stability), having the stream trait in std means there are no concerns about trait changing during that time ([citation](http://smallcultfollowing.com/babysteps/blog/2019/12/23/async-interview-3-carl-lerche/#what-should-we-do-next-stabilize-stream)). +People can do this currently using the [futures](https://crates.io/crates/futures) crate. However, stability guarantees are clearer when traits are added to the standard library than when they exist in a separate crate. For example, if [Tokio](https://tokio.rs/) wishes to declare a [5 year stability period](http://smallcultfollowing.com/babysteps/blog/2020/02/11/async-interview-6-eliza-weisman/#communicating-stability), having the stream trait in std means there are no concerns about trait changing during that time ([citation](http://smallcultfollowing.com/babysteps/blog/2019/12/23/async-interview-3-carl-lerche/#what-should-we-do-next-stabilize-stream)). ## Examples of crates that are consuming streams @@ -172,18 +172,25 @@ Discuss prior art, both the good and the bad, in relation to this proposal. The best example of prior art in Rust is the [futures](https://crates.io/crates/futures) crate. +## Other Rust Examples +* [tokio-rs/async-stream](https://github.com/tokio-rs/async-stream) + +## Rust blog posts/books on Async streams +* [The Stream Trait - Asynchronous Programming in Rust](https://rust-lang.github.io/async-book/05_streams/01_chapter.html) +* [Rust Streams - Yoshua Wuyts](https://blog.yoshuawuyts.com/rust-streams/) +* [For await loops - Boats](https://boats.gitlab.io/blog/page/2/) +* [For await loops - Rust internals post](https://internals.rust-lang.org/t/for-await-loops/9819?u=cad97) +* [On "Async Streams" in Rust - Christopher Durham](https://dev.to/cad97/on-async-streams-in-rust-25eo) +* [Stream combinators implemented using for await syntax](https://www.reddit.com/r/rust/comments/cbvhq9/stream_combinators_implemented_using_for_await/) + + +## Other Languages * Ruby - https://github.com/socketry/async-io * Javascript https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator * more Javascript https://javascript.info/async-iterators-generators * Dart https://dart.dev/tutorials/language/streams - -- For language, library, cargo, tools, and compiler proposals: Does this feature exist in other programming languages and what experience have their community had? -- For community proposals: Is this done by some other community and what were their experiences with it? -- For other teams: What lessons can we learn from what other communities have done here? -- Papers: Are there any published papers or great posts that discuss this? If you have some relevant papers to refer to, this can serve as a more detailed theoretical background. - This section is intended to encourage you as an author to think about the lessons from other languages, provide readers of your RFC with a fuller picture. If there is no prior art, that is fine - your ideas are interesting to us whether they are brand new or if it is an adaptation from other languages. From 7417128bc9d0a71ca3f43e5aaf34c741025b893d Mon Sep 17 00:00:00 2001 From: Nell Shamrell Date: Tue, 2 Jun 2020 18:24:34 -0700 Subject: [PATCH 03/10] adds more to future possibilities Signed-off-by: Nell Shamrell --- rfc-drafts/stream.md | 72 +++++++++++++++++++++++++++++++++----------- 1 file changed, 54 insertions(+), 18 deletions(-) diff --git a/rfc-drafts/stream.md b/rfc-drafts/stream.md index 968bf0bd..a1fbaf0f 100644 --- a/rfc-drafts/stream.md +++ b/rfc-drafts/stream.md @@ -7,15 +7,15 @@ [summary]: #summary Introduce the `Stream` trait into the standard library, using the -design from `futures`. Redirect the futures-stream definition to the -standard library. +design from `futures`. Redirect the `Stream` trait definition in the +`futures` crate to the standard library. # Motivation [motivation]: #motivation Streams are a core async abstraction. We want to enable portable libraries that produce/consume streams without being tied to a particular executor. -People can do this currently using the [futures](https://crates.io/crates/futures) crate. However, stability guarantees are clearer when traits are added to the standard library than when they exist in a separate crate. For example, if [Tokio](https://tokio.rs/) wishes to declare a [5 year stability period](http://smallcultfollowing.com/babysteps/blog/2020/02/11/async-interview-6-eliza-weisman/#communicating-stability), having the stream trait in std means there are no concerns about trait changing during that time ([citation](http://smallcultfollowing.com/babysteps/blog/2019/12/23/async-interview-3-carl-lerche/#what-should-we-do-next-stabilize-stream)). +People can do this currently using the `Stream` trait defined in the [futures](https://crates.io/crates/futures) crate. However, the stability guarantee of that trait would be clearer if it were added to the standard library. For example, if [Tokio](https://tokio.rs/) wishes to declare a [5 year stability period](http://smallcultfollowing.com/babysteps/blog/2020/02/11/async-interview-6-eliza-weisman/#communicating-stability), having the stream trait in std means there are no concerns about trait changing during that time ([citation](http://smallcultfollowing.com/babysteps/blog/2019/12/23/async-interview-3-carl-lerche/#what-should-we-do-next-stabilize-stream)). ## Examples of crates that are consuming streams @@ -33,7 +33,7 @@ We eventually want dedicated syntax for working with streams, which will require ## Why is the stream trait defined how it is? * It is the "pollable iterator" -* dyn compatibility +* [dyn compatibility](https://doc.rust-lang.org/std/keyword.dyn.html) # Guide-level explanation [guide-level-explanation]: #guide-level-explanation @@ -172,9 +172,6 @@ Discuss prior art, both the good and the bad, in relation to this proposal. The best example of prior art in Rust is the [futures](https://crates.io/crates/futures) crate. -## Other Rust Examples -* [tokio-rs/async-stream](https://github.com/tokio-rs/async-stream) - ## Rust blog posts/books on Async streams * [The Stream Trait - Asynchronous Programming in Rust](https://rust-lang.github.io/async-book/05_streams/01_chapter.html) * [Rust Streams - Yoshua Wuyts](https://blog.yoshuawuyts.com/rust-streams/) @@ -185,11 +182,7 @@ The best example of prior art in Rust is the [futures](https://crates.io/crates/ ## Other Languages -* Ruby - https://github.com/socketry/async-io -* Javascript https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator -* more Javascript https://javascript.info/async-iterators-generators -* Dart https://dart.dev/tutorials/language/streams - +* [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator) This section is intended to encourage you as an author to think about the lessons from other languages, provide readers of your RFC with a fuller picture. If there is no prior art, that is fine - your ideas are interesting to us whether they are brand new or if it is an adaptation from other languages. @@ -254,19 +247,62 @@ Designing such a migration feature is out of scope for this RFC. ## Async iteration syntax -We may wish to introduce some dedicated syntax, analogous to `for` +Currently, if someone wishes to iterate over a `Stream` as defined in the `futures` crate, +they are not able to use `for` loops, they must use `while let` and `next/try_next` instead. + +We may wish to extend the `for` loop so that it works over streams as well. + +```rust +#[async] +for elem in stream { ... } +``` + +Designing this extension is out of scope for this RFC. + +## "Attached" streams + +There has been much discussion around attached/detached streams. + +### Definitions + +[Source](https://smallcultfollowing.com/babysteps/blog/2019/12/10/async-interview-2-cramertj-part-2/#the-need-for-streaming-streams-and-iterators) + +In a **detached** stream, the `Item` that gets returned by `Stream` is "detached" from self. This means it can be stored and moved about independently from `self`. + +In an **attached** stream, the `Item` that gets returned by `Stream` may be borrowed from `self`. It can only be used as long as the `self` reference remains live. + +### Alternate terminology + +An alternative terminology - which may be easier to understand in terms of ownership and borrowed - involves **owned** and **borrowed** streams. + +An **owned** stream is like a **detached** stream. The `Stream` transfers ownership of the `Item` returned by it to you. + +A **borrowed** stream is like an **attached** stream. The `Item` you get back from the `Stream` is borrowed from the `Stream` itself. + +This RFC does not cover the addition of attached/detached owned/borrowed streams. +We can add the `Stream` trait to the standard library now and delay +adding in this distinction between two types of streams. The advantage of this +is it would allow us to copy the `Stream` trait from `futures` largely 'as is'. +The disadvantage of this is functions that consume streams would first be written +to work with `Stream`, and then potentially have to be rewritten later to work with +`AttachedStream`s. ## Generator syntax [generator syntax]: #generator-syntax +In the future, we may wish to introduce a new form of function - +`gen fn` in iterators and `async gen` in async code that +can contain `yield` statements. Calling such a function would +yield a `impl Iterator` or `impl Stream`, for sync and async +respectively. Given an "attached" or "borrowed" stream, the generator +yield could return references to local variables. Given a "detached" +or "owned" stream, the generator yield could return things +that you own or things that were borrowed from your caller. + ```rust gen async fn foo() -> X { yield value; } ``` -## "Attached" streams - -Just as with iterators, there is a - - +Designing generator functions is out of the scope of this RFC. From 16d5ed936664f94fd69d38767b5147703275ab78 Mon Sep 17 00:00:00 2001 From: Nell Shamrell Date: Tue, 2 Jun 2020 18:31:06 -0700 Subject: [PATCH 04/10] more edits Signed-off-by: Nell Shamrell --- rfc-drafts/stream.md | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/rfc-drafts/stream.md b/rfc-drafts/stream.md index a1fbaf0f..0a0083bf 100644 --- a/rfc-drafts/stream.md +++ b/rfc-drafts/stream.md @@ -13,9 +13,16 @@ design from `futures`. Redirect the `Stream` trait definition in the # Motivation [motivation]: #motivation -Streams are a core async abstraction. We want to enable portable libraries that produce/consume streams without being tied to a particular executor. +Streams are a core async abstraction. We want to enable portable libraries that +produce/consume streams without being tied to a particular executor. -People can do this currently using the `Stream` trait defined in the [futures](https://crates.io/crates/futures) crate. However, the stability guarantee of that trait would be clearer if it were added to the standard library. For example, if [Tokio](https://tokio.rs/) wishes to declare a [5 year stability period](http://smallcultfollowing.com/babysteps/blog/2020/02/11/async-interview-6-eliza-weisman/#communicating-stability), having the stream trait in std means there are no concerns about trait changing during that time ([citation](http://smallcultfollowing.com/babysteps/blog/2019/12/23/async-interview-3-carl-lerche/#what-should-we-do-next-stabilize-stream)). +People can do this currently using the `Stream` trait defined in the +[futures](https://crates.io/crates/futures) crate. However, the +stability guarantee of that trait would be clearer if it were added +to the standard library. For example, if [Tokio](https://tokio.rs/) +wishes to declare a [5 year stability period](http://smallcultfollowing.com/babysteps/blog/2020/02/11/async-interview-6-eliza-weisman/#communicating-stability), +having the stream trait in the standard library means there are no concerns +about the trait changing during that time ([citation](http://smallcultfollowing.com/babysteps/blog/2019/12/23/async-interview-3-carl-lerche/#what-should-we-do-next-stabilize-stream)). ## Examples of crates that are consuming streams @@ -126,6 +133,9 @@ why they ended up the way they did. `Stream` will live in the `core::stream` module and be re-exported as `std::stream`. +It is possible that it could live in another area as well, though this followes +the pattern of `core::future`. + ## Why use a `poll` method? An alternative design for the stream trait would be to have a trait @@ -162,28 +172,13 @@ Why should we *not* do this? ## Where should stream live? -* core::stream is analogous to core::future -* but do we want to find some other naming scheme that can scale up to other future additions, such as io traits or channels? +As mentioned above, `core::stream` is analogous to `core::future`. But, do we want to find some other naming scheme that can scale up to other future additions, such as io traits or channels? # Prior art [prior-art]: #prior-art Discuss prior art, both the good and the bad, in relation to this proposal. -The best example of prior art in Rust is the [futures](https://crates.io/crates/futures) crate. - -## Rust blog posts/books on Async streams -* [The Stream Trait - Asynchronous Programming in Rust](https://rust-lang.github.io/async-book/05_streams/01_chapter.html) -* [Rust Streams - Yoshua Wuyts](https://blog.yoshuawuyts.com/rust-streams/) -* [For await loops - Boats](https://boats.gitlab.io/blog/page/2/) -* [For await loops - Rust internals post](https://internals.rust-lang.org/t/for-await-loops/9819?u=cad97) -* [On "Async Streams" in Rust - Christopher Durham](https://dev.to/cad97/on-async-streams-in-rust-25eo) -* [Stream combinators implemented using for await syntax](https://www.reddit.com/r/rust/comments/cbvhq9/stream_combinators_implemented_using_for_await/) - - -## Other Languages -* [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/asyncIterator) - This section is intended to encourage you as an author to think about the lessons from other languages, provide readers of your RFC with a fuller picture. If there is no prior art, that is fine - your ideas are interesting to us whether they are brand new or if it is an adaptation from other languages. From a2b814038c2520d49299777c0af56d66d3514fa3 Mon Sep 17 00:00:00 2001 From: Nell Shamrell Date: Thu, 4 Jun 2020 13:31:21 -0700 Subject: [PATCH 05/10] some corrections Signed-off-by: Nell Shamrell --- rfc-drafts/stream.md | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/rfc-drafts/stream.md b/rfc-drafts/stream.md index 0a0083bf..d5d1c33a 100644 --- a/rfc-drafts/stream.md +++ b/rfc-drafts/stream.md @@ -8,7 +8,7 @@ Introduce the `Stream` trait into the standard library, using the design from `futures`. Redirect the `Stream` trait definition in the -`futures` crate to the standard library. +`futures-core` crate (which is "pub-used" by the `futures` crate) to the standard library. # Motivation [motivation]: #motivation @@ -252,7 +252,7 @@ We may wish to extend the `for` loop so that it works over streams as well. for elem in stream { ... } ``` -Designing this extension is out of scope for this RFC. +Designing this extension is out of scope for this RFC. However, it could be prototyped using procedural macros today. ## "Attached" streams @@ -266,14 +266,6 @@ In a **detached** stream, the `Item` that gets returned by `Stream` is "detached In an **attached** stream, the `Item` that gets returned by `Stream` may be borrowed from `self`. It can only be used as long as the `self` reference remains live. -### Alternate terminology - -An alternative terminology - which may be easier to understand in terms of ownership and borrowed - involves **owned** and **borrowed** streams. - -An **owned** stream is like a **detached** stream. The `Stream` transfers ownership of the `Item` returned by it to you. - -A **borrowed** stream is like an **attached** stream. The `Item` you get back from the `Stream` is borrowed from the `Stream` itself. - This RFC does not cover the addition of attached/detached owned/borrowed streams. We can add the `Stream` trait to the standard library now and delay adding in this distinction between two types of streams. The advantage of this From 4fc7bfd10dc6f8c85f0d5048685fd03baa6cd02f Mon Sep 17 00:00:00 2001 From: Nell Shamrell Date: Thu, 4 Jun 2020 13:56:57 -0700 Subject: [PATCH 06/10] adds more information and code examples to the attached/detached section of the RFC Signed-off-by: Nell Shamrell --- rfc-drafts/stream.md | 51 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/rfc-drafts/stream.md b/rfc-drafts/stream.md index d5d1c33a..98f1590c 100644 --- a/rfc-drafts/stream.md +++ b/rfc-drafts/stream.md @@ -274,6 +274,57 @@ The disadvantage of this is functions that consume streams would first be writte to work with `Stream`, and then potentially have to be rewritten later to work with `AttachedStream`s. +### Current Stream Trait + +```rust +pub trait Stream { + type Item; + + fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll>; + + #[inline] + fn size_hint(&self) -> (usize, Option) { + (0, None) + } +} +``` + +This trait, like `Iterator`, always gives ownership of each item back to its caller. This offers flexibility - +such as the ability to spawn off futures processing each item in parallel. + +### Potential Attached Stream Trait + +```rust +impl AttachedStream for S +where + S: Stream, +{ + type Item<'_> = S::Item; + + fn poll_next<'s>( + self: Pin<&'s mut Self>, + cx: &mut Context<'_>, + ) -> Poll>> { + Stream::poll_next(self, cx) + } +} +``` + +This is a "conversion" trait such that anything which implements `Stream` can also implement +`Attached Stream`. + +This trait captures the case we re-use internal buffers. This would be less flexible for +consumers, but potentially more efficient. Types could implement the `AttachedStream` +where they need to re-use an internal buffer and `Stream` if they do not. There is room for both. + +We would also need to pursue the same design for iterators - whether through adding two traits +or one new trait with a "conversion" from the old trait. + +This also brings up the question of whether we should allow conversion in the opposite way - if +every "Detached" stream can become an attached one, should _some_ detached streams be able to +become attached ones? These use cases need more thought, which is part of the reason +it is out of the scope of this particular RFC. + ## Generator syntax [generator syntax]: #generator-syntax From 2bdeadbd266c5c966a4e8d201ea56721a4b57b3a Mon Sep 17 00:00:00 2001 From: Nell Shamrell Date: Thu, 4 Jun 2020 13:58:57 -0700 Subject: [PATCH 07/10] fix for line length Signed-off-by: Nell Shamrell --- rfc-drafts/stream.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rfc-drafts/stream.md b/rfc-drafts/stream.md index 98f1590c..fefab549 100644 --- a/rfc-drafts/stream.md +++ b/rfc-drafts/stream.md @@ -36,7 +36,8 @@ about the trait changing during that time ([citation](http://smallcultfollowing. ## Why a shared trait? -We eventually want dedicated syntax for working with streams, which will require a shared trait. This includes a trait for producing streams and a trait for consuming streams. +We eventually want dedicated syntax for working with streams, which will require a shared trait. +This includes a trait for producing streams and a trait for consuming streams. ## Why is the stream trait defined how it is? * It is the "pollable iterator" From 20a7160739d355c5917820b0394166831891c9b2 Mon Sep 17 00:00:00 2001 From: Nell Shamrell Date: Fri, 5 Jun 2020 12:21:57 -0700 Subject: [PATCH 08/10] more information Signed-off-by: Nell Shamrell --- rfc-drafts/stream.md | 43 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/rfc-drafts/stream.md b/rfc-drafts/stream.md index fefab549..3fbf035f 100644 --- a/rfc-drafts/stream.md +++ b/rfc-drafts/stream.md @@ -231,15 +231,40 @@ existing code, perhaps as part of an edition migration. Designing such a migration feature is out of scope for this RFC. -## IntoStream / FromStream traits, mirroring iterators - -* currently blocked on async fn in traits -* The exact bounds are unclear. -* the same as combinators -* These would be needed to provide similar iteration semantics as Iterator: - * `for x in iter` uses `impl IntoIterator for T` - * `for x in &iter` uses `impl IntoIterator for &T` - * `for x in &mut iter` uses `impl IntoIterator for &mut T` +## IntoStream / FromStream traits + +The `IntoStream` trait would provide a way to convert something into a `Stream`. + +The `FromStream` trait would provide a way to convert a `Stream` into something else. + +Implementing the `IntoStream` and `FromStream` traits on `Stream` is currently blocked on needing [`async fn` available in traits]( http://smallcultfollowing.com/babysteps/blog/2019/10/26/async-fn-in-traits-are-hard). + +These would need to provide similar iteration semantics as `Iterator`. +* `for x in iter` uses `impl IntoIterator for T` +* `for x in &iter` uses `impl IntoIterator for &T` +* `for x in &mut iter` uses `impl IntoIterator for &mut T` + +The reasons not to do this right now are the same as the reasons for delaying convenience methods. + +## Other Traits + +Eventually, we will also want to add some (if not all) of the roster of traits we found useful for `Iterator`. + +[async_std::stream](https://docs.rs/async-std/1.6.0/async_std/stream/index.html) has created several async counterparts to the traits in [std::iter](https://doc.rust-lang.org/std/iter/). These include: + +``` +DoubleEndedStream # A stream able to yield elements from both ends. +ExactSizeStream # A stream that knows its exact length. +Extend # Extends a collection with the contents of a stream. +FromStream # Conversion from a Stream. +FusedStream # A stream that always continues to yield None when exhausted. +IntoStream # Conversion into a Stream. +Product # Trait to represent types that can be created by multiplying the elements of a stream. +Stream # An asynchronous stream of values. +Sum # Trait to represent types that can be created by summing up a stream. +``` + +As detailed in previous sections, the migrations to add these traits are out of scope for this RFC. ## Async iteration syntax From 7b3c785cee8319004834a058574dcb74723667ca Mon Sep 17 00:00:00 2001 From: Nell Shamrell Date: Fri, 5 Jun 2020 14:07:05 -0700 Subject: [PATCH 09/10] small corrections Signed-off-by: Nell Shamrell --- rfc-drafts/stream.md | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/rfc-drafts/stream.md b/rfc-drafts/stream.md index 3fbf035f..aebde041 100644 --- a/rfc-drafts/stream.md +++ b/rfc-drafts/stream.md @@ -237,8 +237,6 @@ The `IntoStream` trait would provide a way to convert something into a `Stream`. The `FromStream` trait would provide a way to convert a `Stream` into something else. -Implementing the `IntoStream` and `FromStream` traits on `Stream` is currently blocked on needing [`async fn` available in traits]( http://smallcultfollowing.com/babysteps/blog/2019/10/26/async-fn-in-traits-are-hard). - These would need to provide similar iteration semantics as `Iterator`. * `for x in iter` uses `impl IntoIterator for T` * `for x in &iter` uses `impl IntoIterator for &T` @@ -248,21 +246,19 @@ The reasons not to do this right now are the same as the reasons for delaying co ## Other Traits -Eventually, we will also want to add some (if not all) of the roster of traits we found useful for `Iterator`. +Eventually, we may also want to add some (if not all) of the roster of traits we found useful for `Iterator`. [async_std::stream](https://docs.rs/async-std/1.6.0/async_std/stream/index.html) has created several async counterparts to the traits in [std::iter](https://doc.rust-lang.org/std/iter/). These include: -``` -DoubleEndedStream # A stream able to yield elements from both ends. -ExactSizeStream # A stream that knows its exact length. -Extend # Extends a collection with the contents of a stream. -FromStream # Conversion from a Stream. -FusedStream # A stream that always continues to yield None when exhausted. -IntoStream # Conversion into a Stream. -Product # Trait to represent types that can be created by multiplying the elements of a stream. -Stream # An asynchronous stream of values. -Sum # Trait to represent types that can be created by summing up a stream. -``` +* DoubleEndedStream: A stream able to yield elements from both ends. +* ExactSizeStream: A stream that knows its exact length. +* Extend: Extends a collection with the contents of a stream. +* FromStream: Conversion from a Stream. +* FusedStream: A stream that always continues to yield None when exhausted. +* IntoStream: Conversion into a Stream. +* Product: Trait to represent types that can be created by multiplying the elements of a stream. +* Stream: An asynchronous stream of values. +* Sum: Trait to represent types that can be created by summing up a stream. As detailed in previous sections, the migrations to add these traits are out of scope for this RFC. From 455e9741d64ddaff05389651ad5d1999a642e2d0 Mon Sep 17 00:00:00 2001 From: Nell Shamrell Date: Fri, 5 Jun 2020 14:15:39 -0700 Subject: [PATCH 10/10] more corrections - mark places for addition Signed-off-by: Nell Shamrell --- rfc-drafts/stream.md | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/rfc-drafts/stream.md b/rfc-drafts/stream.md index aebde041..84d1981b 100644 --- a/rfc-drafts/stream.md +++ b/rfc-drafts/stream.md @@ -233,16 +233,29 @@ Designing such a migration feature is out of scope for this RFC. ## IntoStream / FromStream traits -The `IntoStream` trait would provide a way to convert something into a `Stream`. +### IntoStream -The `FromStream` trait would provide a way to convert a `Stream` into something else. +Iterators have an `IntoIterator` that is used with `for` loops to convert items of other types to an iterator. -These would need to provide similar iteration semantics as `Iterator`. * `for x in iter` uses `impl IntoIterator for T` * `for x in &iter` uses `impl IntoIterator for &T` * `for x in &mut iter` uses `impl IntoIterator for &mut T` -The reasons not to do this right now are the same as the reasons for delaying convenience methods. +We may want a trait similar to this for `Stream`. The `IntoStream` trait would provide a way to convert something into a `Stream`. + +This trait could look like this: + +[TO BE ADDED] + +### FromStream + +Iterators have an `FromIterator` that is used to convert iterators into another type. + +We may want a trait similar to this for `Stream`. The `FromStream` trait would provide way to convert a `Stream` into another type. + +This trait could look like this: + +[TO BE ADDED] ## Other Traits