Skip to content

Commit

Permalink
Align io::Cursor implementations with std
Browse files Browse the repository at this point in the history
Instead of providing a generic `AsyncWrite` implementation delegate the
specific implementations of `Write`.
  • Loading branch information
Nemo157 authored and cramertj committed Nov 4, 2019
1 parent 7a74262 commit 5eaf178
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 46 deletions.
40 changes: 11 additions & 29 deletions futures-io/src/lib.rs
Expand Up @@ -26,7 +26,6 @@ compile_error!("The `read_initializer` feature requires the `unstable` feature a

#[cfg(feature = "std")]
mod if_std {
use std::cmp;
use std::io;
use std::ops::DerefMut;
use std::pin::Pin;
Expand Down Expand Up @@ -472,37 +471,20 @@ mod if_std {
}
}

impl<T: AsMut<[u8]> + Unpin> AsyncWrite for io::Cursor<T> {
fn poll_write(
mut self: Pin<&mut Self>,
_: &mut Context<'_>,
buf: &[u8],
) -> Poll<Result<usize>> {
let position = self.position();
let result = {
let out = (&mut *self).get_mut().as_mut();
let pos = cmp::min(out.len() as u64, position) as usize;
io::Write::write(&mut &mut out[pos..], buf)
};
if let Ok(offset) = result {
self.get_mut().set_position(position + offset as u64);
}
Poll::Ready(result)
}
impl AsyncWrite for io::Cursor<&mut [u8]> {
delegate_async_write_to_stdio!();
}

fn poll_write_vectored(self: Pin<&mut Self>, _: &mut Context<'_>, bufs: &[IoSlice<'_>])
-> Poll<Result<usize>>
{
Poll::Ready(io::Write::write_vectored(&mut self.get_mut().get_mut().as_mut(), bufs))
}
impl AsyncWrite for io::Cursor<&mut Vec<u8>> {
delegate_async_write_to_stdio!();
}

fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<()>> {
Poll::Ready(io::Write::flush(&mut self.get_mut().get_mut().as_mut()))
}
impl AsyncWrite for io::Cursor<Vec<u8>> {
delegate_async_write_to_stdio!();
}

fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<()>> {
self.poll_flush(cx)
}
impl AsyncWrite for io::Cursor<Box<[u8]>> {
delegate_async_write_to_stdio!();
}

impl AsyncWrite for Vec<u8> {
Expand Down
14 changes: 7 additions & 7 deletions futures-test/src/io/write/mod.rs
Expand Up @@ -19,17 +19,17 @@ pub trait AsyncWriteTestExt: AsyncWrite {
/// use futures_test::io::AsyncWriteTestExt;
/// use futures::pin_mut;
///
/// let writer = std::io::Cursor::new([0u8; 4]).interleave_pending_write();
/// let writer = std::io::Cursor::new(vec![0u8; 4].into_boxed_slice()).interleave_pending_write();
/// pin_mut!(writer);
///
/// let mut cx = noop_context();
///
/// assert_eq!(writer.as_mut().poll_write(&mut cx, &[1, 2])?, Poll::Pending);
/// assert_eq!(writer.as_mut().poll_write(&mut cx, &[1, 2])?, Poll::Ready(2));
/// assert_eq!(writer.get_ref().get_ref(), &[1, 2, 0, 0]);
/// assert_eq!(&writer.get_ref().get_ref()[..], [1, 2, 0, 0]);
/// assert_eq!(writer.as_mut().poll_write(&mut cx, &[3, 4])?, Poll::Pending);
/// assert_eq!(writer.as_mut().poll_write(&mut cx, &[3, 4])?, Poll::Ready(2));
/// assert_eq!(writer.get_ref().get_ref(), &[1, 2, 3, 4]);
/// assert_eq!(&writer.get_ref().get_ref()[..], [1, 2, 3, 4]);
/// assert_eq!(writer.as_mut().poll_write(&mut cx, &[5, 6])?, Poll::Pending);
/// assert_eq!(writer.as_mut().poll_write(&mut cx, &[5, 6])?, Poll::Ready(0));
///
Expand Down Expand Up @@ -59,17 +59,17 @@ pub trait AsyncWriteTestExt: AsyncWrite {
/// use futures_test::io::AsyncWriteTestExt;
/// use futures::pin_mut;
///
/// let writer = std::io::Cursor::new([0u8; 4]).limited_write(2);
/// let writer = std::io::Cursor::new(vec![0u8; 4].into_boxed_slice()).limited_write(2);
/// pin_mut!(writer);
///
/// let mut cx = noop_context();
///
/// assert_eq!(writer.as_mut().poll_write(&mut cx, &[1, 2])?, Poll::Ready(2));
/// assert_eq!(writer.get_ref().get_ref(), &[1, 2, 0, 0]);
/// assert_eq!(&writer.get_ref().get_ref()[..], [1, 2, 0, 0]);
/// assert_eq!(writer.as_mut().poll_write(&mut cx, &[3])?, Poll::Ready(1));
/// assert_eq!(writer.get_ref().get_ref(), &[1, 2, 3, 0]);
/// assert_eq!(&writer.get_ref().get_ref()[..], [1, 2, 3, 0]);
/// assert_eq!(writer.as_mut().poll_write(&mut cx, &[4, 5])?, Poll::Ready(1));
/// assert_eq!(writer.get_ref().get_ref(), &[1, 2, 3, 4]);
/// assert_eq!(&writer.get_ref().get_ref()[..], [1, 2, 3, 4]);
/// assert_eq!(writer.as_mut().poll_write(&mut cx, &[5])?, Poll::Ready(0));
///
/// # Ok::<(), std::io::Error>(())
Expand Down
14 changes: 7 additions & 7 deletions futures-util/src/io/mod.rs
Expand Up @@ -172,7 +172,7 @@ pub trait AsyncReadExt: AsyncRead {
/// use std::io::Cursor;
///
/// let reader = Cursor::new([1, 2, 3, 4]);
/// let mut writer = Cursor::new([0u8; 5]);
/// let mut writer = Cursor::new(vec![0u8; 5]);
///
/// let bytes = reader.copy_into(&mut writer).await?;
/// writer.close().await?;
Expand Down Expand Up @@ -354,8 +354,8 @@ pub trait AsyncReadExt: AsyncRead {
/// // implement both `AsyncRead` and `AsyncWrite`.
///
/// let reader = Cursor::new([1, 2, 3, 4]);
/// let mut buffer = Cursor::new([0, 0, 0, 0, 5, 6, 7, 8]);
/// let mut writer = Cursor::new([0u8; 5]);
/// let mut buffer = Cursor::new(vec![0, 0, 0, 0, 5, 6, 7, 8]);
/// let mut writer = Cursor::new(vec![0u8; 5]);
///
/// {
/// let (buffer_reader, mut buffer_writer) = (&mut buffer).split();
Expand Down Expand Up @@ -426,10 +426,10 @@ pub trait AsyncWriteExt: AsyncWrite {
/// use futures::io::{AllowStdIo, AsyncWriteExt};
/// use std::io::{BufWriter, Cursor};
///
/// let mut output = [0u8; 5];
/// let mut output = vec![0u8; 5];
///
/// {
/// let writer = Cursor::new(&mut output[..]);
/// let writer = Cursor::new(&mut output);
/// let mut buffered = AllowStdIo::new(BufWriter::new(writer));
/// buffered.write_all(&[1, 2]).await?;
/// buffered.write_all(&[3, 4]).await?;
Expand Down Expand Up @@ -487,7 +487,7 @@ pub trait AsyncWriteExt: AsyncWrite {
/// use futures::io::AsyncWriteExt;
/// use std::io::Cursor;
///
/// let mut writer = Cursor::new([0u8; 5]);
/// let mut writer = Cursor::new(vec![0u8; 5]);
///
/// writer.write_all(&[1, 2, 3, 4]).await?;
///
Expand Down Expand Up @@ -582,7 +582,7 @@ pub trait AsyncBufReadExt: AsyncBufRead {
/// use std::io::Cursor;
///
/// let reader = Cursor::new([1, 2, 3, 4]);
/// let mut writer = Cursor::new([0u8; 5]);
/// let mut writer = Cursor::new(vec![0u8; 5]);
///
/// let bytes = reader.copy_buf_into(&mut writer).await?;
/// writer.close().await?;
Expand Down
18 changes: 15 additions & 3 deletions futures/tests/io_cursor.rs
Expand Up @@ -6,13 +6,25 @@ use std::io::Cursor;
use std::pin::Pin;

#[test]
fn cursor_asyncwrite_asmut() {
let mut cursor = Cursor::new([0; 5]);
fn cursor_asyncwrite_vec() {
let mut cursor = Cursor::new(vec![0; 5]);
futures::executor::block_on(lazy(|cx| {
assert_matches!(Pin::new(&mut cursor).poll_write(cx, &[1, 2]), Poll::Ready(Ok(2)));
assert_matches!(Pin::new(&mut cursor).poll_write(cx, &[3, 4]), Poll::Ready(Ok(2)));
assert_matches!(Pin::new(&mut cursor).poll_write(cx, &[5, 6]), Poll::Ready(Ok(2)));
assert_matches!(Pin::new(&mut cursor).poll_write(cx, &[6, 7]), Poll::Ready(Ok(2)));
}));
assert_eq!(cursor.into_inner(), [1, 2, 3, 4, 5, 6, 6, 7]);
}

#[test]
fn cursor_asyncwrite_box() {
let mut cursor = Cursor::new(vec![0; 5].into_boxed_slice());
futures::executor::block_on(lazy(|cx| {
assert_matches!(Pin::new(&mut cursor).poll_write(cx, &[1, 2]), Poll::Ready(Ok(2)));
assert_matches!(Pin::new(&mut cursor).poll_write(cx, &[3, 4]), Poll::Ready(Ok(2)));
assert_matches!(Pin::new(&mut cursor).poll_write(cx, &[5, 6]), Poll::Ready(Ok(1)));
assert_matches!(Pin::new(&mut cursor).poll_write(cx, &[6, 7]), Poll::Ready(Ok(0)));
}));
assert_eq!(cursor.into_inner(), [1, 2, 3, 4, 5]);
assert_eq!(&*cursor.into_inner(), [1, 2, 3, 4, 5]);
}

0 comments on commit 5eaf178

Please sign in to comment.