Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add stream::Zip trait #63

Open
4 of 5 tasks
yoshuawuyts opened this issue Nov 13, 2022 · 2 comments
Open
4 of 5 tasks

Add stream::Zip trait #63

yoshuawuyts opened this issue Nov 13, 2022 · 2 comments
Labels
api design Relates to the user-facing API

Comments

@yoshuawuyts
Copy link
Owner

yoshuawuyts commented Nov 13, 2022

This is a core iteration "order of execution" operation, enabling people to author:

after

let s1 = async_iter::repeat(0).take(5);
let s2 = async_iter::repeat(1).take(5);
let s3 = async_iter::repeat(2).take(5);

for await (n1, n2, n3) in (s1, s2, s3).zip() {
    assert_eq!((n1, n2, n3), (0, 1, 2));
}

This is better than the nested tuple approach of non-trait based zip.

Design

pub trait Zip {
    /// What's the return type of our stream?
    type Item;

    /// What stream do we return?
    type Stream: Stream<Item = Self::Item>;

    /// Combine multiple streams into a single stream.
    fn zip(self) -> Self::Stream;
}

Tasks

@yoshuawuyts yoshuawuyts added the api design Relates to the user-facing API label Nov 13, 2022
@yoshuawuyts
Copy link
Owner Author

For the Zip variant: we may want to skip directly ahead to #22 in terms of implementation, creating an output slot of Container[MaybUninit<T>] where we write into, and then mem::swap on each iteration.

Metadata would need to be stored in an accompanying PollState slot. The main things to keep an eye will be to:

  • ensure to implement the PinnedDrop trait to drop memory in the case of a cancellation
  • switch between PollState::Pending and PollState::Ready while data is actively being yielded, and only switch to PollState::Consume at the end.

The semantics of Zip are that if at any point one of the streams yields Poll::Ready(None), all other streams are cancelled. We should create a case where one stream yields more times than the other streams so that we can exercise miri's checkers during CI.

@yoshuawuyts
Copy link
Owner Author

Filed a concern in rust-lang/rust#80094 since its existence requires us to author:

let mut s = Zip::zip([a, b, c]);

instead of:

let mut s = [a, b, c].zip();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api design Relates to the user-facing API
Projects
None yet
Development

No branches or pull requests

1 participant