From cf2003bccbe8d7d632549bd441c37878e74e5571 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Wed, 6 Nov 2019 00:10:19 +0900 Subject: [PATCH] Change copy_into/copy_buf_into to free functions for consistency with the standard library --- futures-util/src/io/copy.rs | 63 +++++++++++++++ .../src/io/{copy_buf_into.rs => copy_buf.rs} | 57 +++++++++---- futures-util/src/io/copy_into.rs | 34 -------- futures-util/src/io/mod.rs | 80 ++----------------- futures/src/lib.rs | 4 +- 5 files changed, 114 insertions(+), 124 deletions(-) create mode 100644 futures-util/src/io/copy.rs rename futures-util/src/io/{copy_buf_into.rs => copy_buf.rs} (50%) delete mode 100644 futures-util/src/io/copy_into.rs diff --git a/futures-util/src/io/copy.rs b/futures-util/src/io/copy.rs new file mode 100644 index 0000000000..9531aab996 --- /dev/null +++ b/futures-util/src/io/copy.rs @@ -0,0 +1,63 @@ +use futures_core::future::Future; +use futures_core::task::{Context, Poll}; +use futures_io::{AsyncRead, AsyncWrite}; +use std::io; +use std::pin::Pin; +use super::{BufReader, copy_buf, CopyBuf}; +use pin_utils::unsafe_pinned; + +/// Creates a future which copies all the bytes from one object to another. +/// +/// The returned future will copy all the bytes read from this `AsyncRead` into the +/// `writer` specified. This future will only complete once the `reader` has hit +/// EOF and all bytes have been written to and flushed from the `writer` +/// provided. +/// +/// On success the number of bytes is returned. +/// +/// # Examples +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::io::{self, AsyncWriteExt, Cursor}; +/// +/// let reader = Cursor::new([1, 2, 3, 4]); +/// let mut writer = Cursor::new(vec![0u8; 5]); +/// +/// let bytes = io::copy(reader, &mut writer).await?; +/// writer.close().await?; +/// +/// assert_eq!(bytes, 4); +/// assert_eq!(writer.into_inner(), [1, 2, 3, 4, 0]); +/// # Ok::<(), Box>(()) }).unwrap(); +/// ``` +pub fn copy(reader: R, writer: &mut W) -> Copy<'_, R, W> +where + R: AsyncRead, + W: AsyncWrite + Unpin + ?Sized, +{ + Copy { + inner: copy_buf(BufReader::new(reader), writer), + } +} + +/// Future for the [`copy()`] function. +#[derive(Debug)] +#[must_use = "futures do nothing unless you `.await` or poll them"] +pub struct Copy<'a, R, W: ?Sized> { + inner: CopyBuf<'a, BufReader, W>, +} + +impl<'a, R: AsyncRead, W: ?Sized> Unpin for Copy<'a, R, W> where CopyBuf<'a, BufReader, W>: Unpin {} + +impl<'a, R: AsyncRead, W: ?Sized> Copy<'a, R, W> { + unsafe_pinned!(inner: CopyBuf<'a, BufReader, W>); +} + +impl Future for Copy<'_, R, W> { + type Output = io::Result; + + fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + self.inner().poll(cx) + } +} diff --git a/futures-util/src/io/copy_buf_into.rs b/futures-util/src/io/copy_buf.rs similarity index 50% rename from futures-util/src/io/copy_buf_into.rs rename to futures-util/src/io/copy_buf.rs index 0eb3d07399..98811825e0 100644 --- a/futures-util/src/io/copy_buf_into.rs +++ b/futures-util/src/io/copy_buf.rs @@ -4,28 +4,55 @@ use futures_io::{AsyncBufRead, AsyncWrite}; use std::io; use std::pin::Pin; -/// Future for the [`copy_buf_into`](super::AsyncBufReadExt::copy_buf_into) method. +/// Creates a future which copies all the bytes from one object to another. +/// +/// The returned future will copy all the bytes read from this `AsyncBufRead` into the +/// `writer` specified. This future will only complete once the `reader` has hit +/// EOF and all bytes have been written to and flushed from the `writer` +/// provided. +/// +/// On success the number of bytes is returned. +/// +/// # Examples +/// +/// ``` +/// # futures::executor::block_on(async { +/// use futures::io::{self, AsyncWriteExt, Cursor}; +/// +/// let reader = Cursor::new([1, 2, 3, 4]); +/// let mut writer = Cursor::new(vec![0u8; 5]); +/// +/// let bytes = io::copy_buf(reader, &mut writer).await?; +/// writer.close().await?; +/// +/// assert_eq!(bytes, 4); +/// assert_eq!(writer.into_inner(), [1, 2, 3, 4, 0]); +/// # Ok::<(), Box>(()) }).unwrap(); +/// ``` +pub fn copy_buf(reader: R, writer: &mut W) -> CopyBuf<'_, R, W> +where + R: AsyncBufRead, + W: AsyncWrite + Unpin + ?Sized, +{ + CopyBuf { + reader, + writer, + amt: 0, + } +} + +/// Future for the [`copy_buf()`] function. #[derive(Debug)] #[must_use = "futures do nothing unless you `.await` or poll them"] -pub struct CopyBufInto<'a, R, W: ?Sized> { +pub struct CopyBuf<'a, R, W: ?Sized> { reader: R, writer: &'a mut W, amt: u64, } -impl Unpin for CopyBufInto<'_, R, W> {} - -impl CopyBufInto<'_, R, W> { - pub(super) fn new(reader: R, writer: &mut W) -> CopyBufInto<'_, R, W> { - CopyBufInto { - reader, - writer, - amt: 0, - } - } -} +impl Unpin for CopyBuf<'_, R, W> {} -impl CopyBufInto<'_, R, W> { +impl CopyBuf<'_, R, W> { fn project(self: Pin<&mut Self>) -> (Pin<&mut R>, Pin<&mut W>, &mut u64) { unsafe { let this = self.get_unchecked_mut(); @@ -34,7 +61,7 @@ impl CopyBufInto<'_, R, W> { } } -impl Future for CopyBufInto<'_, R, W> +impl Future for CopyBuf<'_, R, W> where R: AsyncBufRead, W: AsyncWrite + Unpin + ?Sized, { diff --git a/futures-util/src/io/copy_into.rs b/futures-util/src/io/copy_into.rs deleted file mode 100644 index 854e3fc474..0000000000 --- a/futures-util/src/io/copy_into.rs +++ /dev/null @@ -1,34 +0,0 @@ -use futures_core::future::Future; -use futures_core::task::{Context, Poll}; -use futures_io::{AsyncRead, AsyncWrite}; -use std::io; -use std::pin::Pin; -use super::{BufReader, CopyBufInto}; -use pin_utils::unsafe_pinned; - -/// Future for the [`copy_into`](super::AsyncReadExt::copy_into) method. -#[derive(Debug)] -#[must_use = "futures do nothing unless you `.await` or poll them"] -pub struct CopyInto<'a, R, W: ?Sized> { - inner: CopyBufInto<'a, BufReader, W>, -} - -impl<'a, R: AsyncRead, W: ?Sized> Unpin for CopyInto<'a, R, W> where CopyBufInto<'a, BufReader, W>: Unpin {} - -impl<'a, R: AsyncRead, W: ?Sized> CopyInto<'a, R, W> { - unsafe_pinned!(inner: CopyBufInto<'a, BufReader, W>); - - pub(super) fn new(reader: R, writer: &mut W) -> CopyInto<'_, R, W> { - CopyInto { - inner: CopyBufInto::new(BufReader::new(reader), writer), - } - } -} - -impl Future for CopyInto<'_, R, W> { - type Output = io::Result; - - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - self.inner().poll(cx) - } -} diff --git a/futures-util/src/io/mod.rs b/futures-util/src/io/mod.rs index 3c00b3f0cc..43f183f424 100644 --- a/futures-util/src/io/mod.rs +++ b/futures-util/src/io/mod.rs @@ -53,11 +53,11 @@ pub use self::chain::Chain; mod close; pub use self::close::Close; -mod copy_into; -pub use self::copy_into::CopyInto; +mod copy; +pub use self::copy::{copy, Copy}; -mod copy_buf_into; -pub use self::copy_buf_into::CopyBufInto; +mod copy_buf; +pub use self::copy_buf::{copy_buf, CopyBuf}; mod cursor; pub use self::cursor::Cursor; @@ -157,39 +157,6 @@ pub trait AsyncReadExt: AsyncRead { Chain::new(self, next) } - /// Creates a future which copies all the bytes from one object to another. - /// - /// The returned future will copy all the bytes read from this `AsyncRead` into the - /// `writer` specified. This future will only complete once the `reader` has hit - /// EOF and all bytes have been written to and flushed from the `writer` - /// provided. - /// - /// On success the number of bytes is returned. - /// - /// # Examples - /// - /// ``` - /// # futures::executor::block_on(async { - /// use futures::io::{AsyncReadExt, AsyncWriteExt, Cursor}; - /// - /// let reader = Cursor::new([1, 2, 3, 4]); - /// let mut writer = Cursor::new(vec![0u8; 5]); - /// - /// let bytes = reader.copy_into(&mut writer).await?; - /// writer.close().await?; - /// - /// assert_eq!(bytes, 4); - /// assert_eq!(writer.into_inner(), [1, 2, 3, 4, 0]); - /// # Ok::<(), Box>(()) }).unwrap(); - /// ``` - fn copy_into(self, writer: &mut W) -> CopyInto<'_, Self, W> - where - Self: Sized, - W: AsyncWrite + Unpin + ?Sized, - { - CopyInto::new(self, writer) - } - /// Tries to read some bytes directly into the given `buf` in asynchronous /// manner, returning a future type. /// @@ -342,7 +309,7 @@ pub trait AsyncReadExt: AsyncRead { /// /// ``` /// # futures::executor::block_on(async { - /// use futures::io::{AsyncReadExt, Cursor}; + /// use futures::io::{self, AsyncReadExt, Cursor}; /// /// // Note that for `Cursor` the read and write halves share a single /// // seek position. This may or may not be true for other types that @@ -354,8 +321,8 @@ pub trait AsyncReadExt: AsyncRead { /// /// { /// let (buffer_reader, mut buffer_writer) = (&mut buffer).split(); - /// reader.copy_into(&mut buffer_writer).await?; - /// buffer_reader.copy_into(&mut writer).await?; + /// io::copy(reader, &mut buffer_writer).await?; + /// io::copy(buffer_reader, &mut writer).await?; /// } /// /// assert_eq!(buffer.into_inner(), [1, 2, 3, 4, 5, 6, 7, 8]); @@ -558,39 +525,6 @@ impl AsyncSeekExt for S {} /// An extension trait which adds utility methods to `AsyncBufRead` types. pub trait AsyncBufReadExt: AsyncBufRead { - /// Creates a future which copies all the bytes from one object to another. - /// - /// The returned future will copy all the bytes read from this `AsyncBufRead` into the - /// `writer` specified. This future will only complete once the `reader` has hit - /// EOF and all bytes have been written to and flushed from the `writer` - /// provided. - /// - /// On success the number of bytes is returned. - /// - /// # Examples - /// - /// ``` - /// # futures::executor::block_on(async { - /// use futures::io::{AsyncBufReadExt, AsyncWriteExt, Cursor}; - /// - /// let reader = Cursor::new([1, 2, 3, 4]); - /// let mut writer = Cursor::new(vec![0u8; 5]); - /// - /// let bytes = reader.copy_buf_into(&mut writer).await?; - /// writer.close().await?; - /// - /// assert_eq!(bytes, 4); - /// assert_eq!(writer.into_inner(), [1, 2, 3, 4, 0]); - /// # Ok::<(), Box>(()) }).unwrap(); - /// ``` - fn copy_buf_into(self, writer: &mut W) -> CopyBufInto<'_, Self, W> - where - Self: Sized, - W: AsyncWrite + Unpin + ?Sized, - { - CopyBufInto::new(self, writer) - } - /// Creates a future which will read all the bytes associated with this I/O /// object into `buf` until the delimiter `byte` or EOF is reached. /// This method is the async equivalent to [`BufRead::read_until`](std::io::BufRead::read_until). diff --git a/futures/src/lib.rs b/futures/src/lib.rs index 7fe16c8e33..8c0b04df94 100644 --- a/futures/src/lib.rs +++ b/futures/src/lib.rs @@ -134,7 +134,7 @@ pub mod executor { //! than threads). Tasks spawned onto the pool with the //! [`spawn_ok()`](crate::executor::ThreadPool::spawn_ok) //! function will run on ambiently on the created threads. - //! + //! //! # Spawning additional tasks //! //! Tasks can be spawned onto a spawner by calling its @@ -271,7 +271,7 @@ pub mod io { pub use futures_util::io::{ AsyncReadExt, AsyncWriteExt, AsyncSeekExt, AsyncBufReadExt, AllowStdIo, - BufReader, BufWriter, Cursor, Chain, Close, CopyInto, CopyBufInto, + BufReader, BufWriter, Cursor, Chain, Close, copy, Copy, copy_buf, CopyBuf, empty, Empty, Flush, IntoSink, Lines, Read, ReadExact, ReadHalf, ReadLine, ReadToEnd, ReadToString, ReadUntil, ReadVectored, repeat, Repeat, Seek, sink, Sink, Take, Window, Write, WriteAll, WriteHalf,