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 StreamExt::copy_into #1661

Closed
yoshuawuyts opened this issue Jun 6, 2019 · 1 comment
Closed

Add StreamExt::copy_into #1661

yoshuawuyts opened this issue Jun 6, 2019 · 1 comment

Comments

@yoshuawuyts
Copy link
Member

@yoshuawuyts yoshuawuyts commented Jun 6, 2019

Problem definition

Currently in order to move data from an AsyncRead into an AsyncWrite you can use the copy_into method.

However when wanting to move data from a Stream<Item = Vec<u8>> into an AsyncWrite, we have to perform the slightly awkward dance of:

stream.map(io::Result::Ok).into_async_read().copy_into(writer)

This is not only hard to remember, but has a double buffering problem (see #1659 for a proposal to address this).

Proposal

It'd be nice if copy_into would work for byte streams too:

stream.copy_into(writer)

This could be implemented along the lines of:

impl Stream<Item = AsRef<[u8]>> {
    pub fn copy_into(&mut self, writer: impl AsyncWrite) -> /* ret */ {
        self.for_each(move |buf| writer.write(buf))
    }
}

impl Stream<Item = io::Result<AsRef<[u8]>>> {
    pub fn copy_into(&mut self, writer: impl AsyncWrite) -> /* ret */ {
        self.try_for_each(move |buf| writer.write(buf))
    }
}

Other Considerations

So far I've only encountered example uses for this in the wild moving data from Stream -> AsyncWrite. It might be possible to add similar conversions for other traits too, but I think it would be best to keep the conversation about Stream<[u8]> -> AsyncWrite first, to limit the scope of this proposal.

Related Issues

@yoshuawuyts
Copy link
Member Author

@yoshuawuyts yoshuawuyts commented Nov 21, 2020

A better solution in the future would be through external iteration using async iteration syntax:

for buf.await? in stream {
    writer.write(buf)?;
}

This is far more flexible than an adapter-based approach and works past the problems outlined in this issue. It can already be emulated using while let Some loops.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants