diff --git a/tokio/src/io/join.rs b/tokio/src/io/join.rs index 84030948af8..668c040a2ba 100644 --- a/tokio/src/io/join.rs +++ b/tokio/src/io/join.rs @@ -7,116 +7,122 @@ use std::io; use std::pin::Pin; use std::task::{Context, Poll}; -cfg_io_util! { - pin_project_lite::pin_project! { - /// Joins two values implementing `AsyncRead` and `AsyncWrite` into a - /// single handle. - pub struct Join { - #[pin] - reader: R, - #[pin] - writer: W, - } +/// Join two values implementing `AsyncRead` and `AsyncWrite` into a +/// single handle. +pub fn join(reader: R, writer: W) -> Join +where + R: AsyncRead, + W: AsyncWrite, +{ + Join { reader, writer } +} + +pin_project_lite::pin_project! { + /// Joins two values implementing `AsyncRead` and `AsyncWrite` into a + /// single handle. + pub struct Join { + #[pin] + reader: R, + #[pin] + writer: W, + } +} + +impl Join +where + R: AsyncRead, + W: AsyncWrite, +{ + /// Splits this `Join` back into its `AsyncRead` and `AsyncWrite` + /// components. + pub fn into_inner(self) -> (R, W) { + (self.reader, self.writer) + } + + /// Returns a reference to the inner reader. + pub fn reader(&self) -> &R { + &self.reader + } + + /// Returns a reference to the inner writer. + pub fn writer(&self) -> &W { + &self.writer + } + + /// Returns a mutable reference to the inner reader. + pub fn reader_mut(&mut self) -> &mut R { + &mut self.reader + } + + /// Returns a mutable reference to the inner writer. + pub fn writer_mut(&mut self) -> &mut W { + &mut self.writer } - impl Join - where - R: AsyncRead + Unpin, - W: AsyncWrite + Unpin, - { - /// Join two values implementing `AsyncRead` and `AsyncWrite` into a - /// single handle. - pub fn new(reader: R, writer: W) -> Self { - Self { reader, writer } - } - - /// Splits this `Join` back into its `AsyncRead` and `AsyncWrite` - /// components. - pub fn split(self) -> (R, W) { - (self.reader, self.writer) - } - - /// Returns a reference to the inner reader. - pub fn reader(&self) -> &R { - &self.reader - } - - /// Returns a reference to the inner writer. - pub fn writer(&self) -> &W { - &self.writer - } - - /// Returns a mutable reference to the inner reader. - pub fn reader_mut(&mut self) -> &mut R { - &mut self.reader - } - - /// Returns a mutable reference to the inner writer. - pub fn writer_mut(&mut self) -> &mut W { - &mut self.writer - } + pub fn reader_pin_mut(self: Pin<&mut Self>) -> Pin<&mut R> { + self.project().reader } - impl AsyncRead for Join - where - R: AsyncRead + Unpin, - { - fn poll_read( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - buf: &mut ReadBuf<'_>, - ) -> Poll> { - self.project().reader.poll_read(cx, buf) - } + pub fn writer_pin_mut(self: Pin<&mut Self>) -> Pin<&mut W> { + self.project().writer } +} + +impl AsyncRead for Join +where + R: AsyncRead + Unpin, +{ + fn poll_read( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut ReadBuf<'_>, + ) -> Poll> { + self.project().reader.poll_read(cx, buf) + } +} - impl AsyncWrite for Join - where - W: AsyncWrite + Unpin, - { - fn poll_write( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - buf: &[u8], - ) -> Poll> { - self.project().writer.poll_write(cx, buf) - } - - fn poll_flush( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll> { - self.project().writer.poll_flush(cx) - } - - fn poll_shutdown( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - ) -> Poll> { - self.project().writer.poll_shutdown(cx) - } - - fn poll_write_vectored( - self: Pin<&mut Self>, - cx: &mut Context<'_>, - bufs: &[io::IoSlice<'_>] - ) -> Poll> { - self.project().writer.poll_write_vectored(cx, bufs) - } - - fn is_write_vectored(&self) -> bool { - self.writer.is_write_vectored() - } +impl AsyncWrite for Join +where + W: AsyncWrite + Unpin, +{ + fn poll_write( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + self.project().writer.poll_write(cx, buf) } - impl fmt::Debug for Join - where R: fmt::Debug, W: fmt::Debug - { - fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt.debug_struct("Join") - .field("writer", &self.writer) - .field("reader", &self.reader) - .finish() - } + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.project().writer.poll_flush(cx) + } + + fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + self.project().writer.poll_shutdown(cx) + } + + fn poll_write_vectored( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + bufs: &[io::IoSlice<'_>], + ) -> Poll> { + self.project().writer.poll_write_vectored(cx, bufs) + } + + fn is_write_vectored(&self) -> bool { + self.writer.is_write_vectored() + } +} + +impl fmt::Debug for Join +where + R: fmt::Debug, + W: fmt::Debug, +{ + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt.debug_struct("Join") + .field("writer", &self.writer) + .field("reader", &self.reader) + .finish() } } diff --git a/tokio/src/io/mod.rs b/tokio/src/io/mod.rs index 11bdf75f4cf..ff35a0e0f7e 100644 --- a/tokio/src/io/mod.rs +++ b/tokio/src/io/mod.rs @@ -266,7 +266,7 @@ cfg_io_util! { mod split; pub use split::{split, ReadHalf, WriteHalf}; mod join; - pub use join::Join; + pub use join::{join, Join}; pub(crate) mod seek; pub(crate) mod util; diff --git a/tokio/tests/io_join.rs b/tokio/tests/io_join.rs index 29f2b7745ca..69b09393311 100644 --- a/tokio/tests/io_join.rs +++ b/tokio/tests/io_join.rs @@ -1,7 +1,7 @@ #![warn(rust_2018_idioms)] -#![cfg(all(feature = "full", not(target_os = "wasi")))] // Wasi does not support panic recovery +#![cfg(feature = "full")] -use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, Join, ReadBuf}; +use tokio::io::{join, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, Join, ReadBuf}; use std::io; use std::pin::Pin; @@ -61,7 +61,7 @@ fn is_send_and_sync() { #[test] fn method_delegation() { - let mut rw = Join::new(R, W); + let mut rw = join(R, W); let mut buf = [0; 1]; tokio_test::block_on(async move {