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

Implement AsyncBufReadExt::copy_buf_into #1674

Merged
merged 4 commits into from
Jun 25, 2019

Conversation

Nemo157
Copy link
Member

@Nemo157 Nemo157 commented Jun 14, 2019

closes #1659

) -> CopyInto<'a, Self, W>
where Self: Unpin, W: AsyncWrite + Unpin,
{
fn copy_into<W: AsyncWrite>(self, writer: W) -> CopyInto<Self, W> where Self: Sized {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be able to re-use CopyBufInto as the implementation of CopyInto I had to make that take the reader and writer by value, it seemed bad to have the two methods be inconsistent so I changed it here as well.

It seems like reusing the reader after copying out of it is unlikely to be a common case, and the only overhead to do so is you will have to (&mut reader).copy_into(&mut writer).await?;, being able to keep the writer accessible after copying doesn't change at all as &mut AsyncWrite + Unpin: AsyncWrite.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you clarify why you had to take it by-value in order to do this? It's somewhat surprising to me that the writer would be by-value (the reader makes decent enough sense, though), especially since we don't poll_close.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Taking the reader by-ref in both cases would look something like:

impl<R: AsyncBufRead + Unpin, W: AsyncWrite + Unpin> CopyBufInto<'_, R, W> {
    fn new(reader: &mut R, writer: &mut W) -> Self { ... }
}

struct CopyInto<'a, R, W> {
    inner: CopyBufInto<'a, R, W>,
}

impl<R: AsyncRead + Unpin, W: AsyncWrite + Unpin> CopyInto<'_, R, W> {
    fn new(reader: &mut R, writer: &mut W) -> Self {
        Self { inner: CopyBufInto::new(&mut BufReader::new(reader), writer) }
    }
}

we want to wrap the reader in a BufReader to allow the reuse, but then we don't have anywhere with ownership of that BufReader when we pass the reference into CopyBufInto::new (unless we make CopyInto a self-referential struct and only create the inner CopyBufInto when we're first polled, but I'd prefer to not deal with manually implemented self-referential structs).

It's somewhat surprising to me that the writer would be by-value

Yeah, I could change the writer back to being by-ref since we don't need to wrap that, but because of impl AsyncWrite for &mut impl AsyncWrite + Unpin you can just pass it by reference anyway (you can see that the example didn't have to change: https://github.com/rust-lang-nursery/futures-rs/pull/1674/files#diff-58a0189b65158d401601a19cc9f17257R104)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's somewhat surprising to me that the writer would be by-value

Yeah, I could change the writer back to being by-ref since we don't need to wrap that, but because of impl AsyncWrite for &mut impl AsyncWrite + Unpin you can just pass it by reference anyway

It may be nice to have an explanation like "Note that this method consumes writer but does not close it.".

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a note.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still skeptical that this is the correct route here-- it seems to me like passing in a non-Pin<&mut T> or &mut T AsyncWrite by-value is basically always going to be a bug. I don't think it's worth changing the API for the sake of consistency with another when the usage should always be different.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 I'll change it back to taking the writer by reference then.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Sorry for the confusing back-and-forth.

@Nemo157 Nemo157 force-pushed the copy-buf-into branch 2 times, most recently from 52e3682 to b937706 Compare June 15, 2019 10:49
@Nemo157 Nemo157 force-pushed the copy-buf-into branch 2 times, most recently from bc34b55 to 8846080 Compare June 25, 2019 17:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Move copy_into from AsyncRead to AsyncBufRead
3 participants