From 5eaf17865545a2d91e50e53b087755735c38771a Mon Sep 17 00:00:00 2001 From: Wim Looman Date: Sun, 3 Nov 2019 12:21:53 +0100 Subject: [PATCH] Align io::Cursor implementations with std Instead of providing a generic `AsyncWrite` implementation delegate the specific implementations of `Write`. --- futures-io/src/lib.rs | 40 +++++++++----------------------- futures-test/src/io/write/mod.rs | 14 +++++------ futures-util/src/io/mod.rs | 14 +++++------ futures/tests/io_cursor.rs | 18 +++++++++++--- 4 files changed, 40 insertions(+), 46 deletions(-) diff --git a/futures-io/src/lib.rs b/futures-io/src/lib.rs index 1372e13c24..cd040ec1bf 100644 --- a/futures-io/src/lib.rs +++ b/futures-io/src/lib.rs @@ -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; @@ -472,37 +471,20 @@ mod if_std { } } - impl + Unpin> AsyncWrite for io::Cursor { - fn poll_write( - mut self: Pin<&mut Self>, - _: &mut Context<'_>, - buf: &[u8], - ) -> Poll> { - 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> - { - Poll::Ready(io::Write::write_vectored(&mut self.get_mut().get_mut().as_mut(), bufs)) - } + impl AsyncWrite for io::Cursor<&mut Vec> { + delegate_async_write_to_stdio!(); + } - fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll> { - Poll::Ready(io::Write::flush(&mut self.get_mut().get_mut().as_mut())) - } + impl AsyncWrite for io::Cursor> { + delegate_async_write_to_stdio!(); + } - fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - self.poll_flush(cx) - } + impl AsyncWrite for io::Cursor> { + delegate_async_write_to_stdio!(); } impl AsyncWrite for Vec { diff --git a/futures-test/src/io/write/mod.rs b/futures-test/src/io/write/mod.rs index cd167c29e2..c94d8541dc 100644 --- a/futures-test/src/io/write/mod.rs +++ b/futures-test/src/io/write/mod.rs @@ -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)); /// @@ -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>(()) diff --git a/futures-util/src/io/mod.rs b/futures-util/src/io/mod.rs index db8bd134d4..dd1fbb6a20 100644 --- a/futures-util/src/io/mod.rs +++ b/futures-util/src/io/mod.rs @@ -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?; @@ -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(); @@ -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?; @@ -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?; /// @@ -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?; diff --git a/futures/tests/io_cursor.rs b/futures/tests/io_cursor.rs index 39c175214a..ad48ed3446 100644 --- a/futures/tests/io_cursor.rs +++ b/futures/tests/io_cursor.rs @@ -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]); }