1//! Join two values implementing `AsyncRead` and `AsyncWrite` into a single one.
2
3use crate::io::{AsyncRead, AsyncWrite, ReadBuf};
4
5use std::io;
6use std::pin::Pin;
7use std::task::{Context, Poll};
8
9/// Join two values implementing `AsyncRead` and `AsyncWrite` into a
10/// single handle.
11pub fn join<R, W>(reader: R, writer: W) -> Join<R, W>
12where
13 R: AsyncRead,
14 W: AsyncWrite,
15{
16 Join { reader, writer }
17}
18
19pin_project_lite::pin_project! {
20 /// Joins two values implementing `AsyncRead` and `AsyncWrite` into a
21 /// single handle.
22 #[derive(Debug)]
23 pub struct Join<R, W> {
24 #[pin]
25 reader: R,
26 #[pin]
27 writer: W,
28 }
29}
30
31impl<R, W> Join<R, W>
32where
33 R: AsyncRead,
34 W: AsyncWrite,
35{
36 /// Splits this `Join` back into its `AsyncRead` and `AsyncWrite`
37 /// components.
38 pub fn into_inner(self) -> (R, W) {
39 (self.reader, self.writer)
40 }
41
42 /// Returns a reference to the inner reader.
43 pub fn reader(&self) -> &R {
44 &self.reader
45 }
46
47 /// Returns a reference to the inner writer.
48 pub fn writer(&self) -> &W {
49 &self.writer
50 }
51
52 /// Returns a mutable reference to the inner reader.
53 pub fn reader_mut(&mut self) -> &mut R {
54 &mut self.reader
55 }
56
57 /// Returns a mutable reference to the inner writer.
58 pub fn writer_mut(&mut self) -> &mut W {
59 &mut self.writer
60 }
61
62 /// Returns a pinned mutable reference to the inner reader.
63 pub fn reader_pin_mut(self: Pin<&mut Self>) -> Pin<&mut R> {
64 self.project().reader
65 }
66
67 /// Returns a pinned mutable reference to the inner writer.
68 pub fn writer_pin_mut(self: Pin<&mut Self>) -> Pin<&mut W> {
69 self.project().writer
70 }
71}
72
73impl<R, W> AsyncRead for Join<R, W>
74where
75 R: AsyncRead,
76{
77 fn poll_read(
78 self: Pin<&mut Self>,
79 cx: &mut Context<'_>,
80 buf: &mut ReadBuf<'_>,
81 ) -> Poll<Result<(), io::Error>> {
82 self.project().reader.poll_read(cx, buf)
83 }
84}
85
86impl<R, W> AsyncWrite for Join<R, W>
87where
88 W: AsyncWrite,
89{
90 fn poll_write(
91 self: Pin<&mut Self>,
92 cx: &mut Context<'_>,
93 buf: &[u8],
94 ) -> Poll<Result<usize, io::Error>> {
95 self.project().writer.poll_write(cx, buf)
96 }
97
98 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
99 self.project().writer.poll_flush(cx)
100 }
101
102 fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
103 self.project().writer.poll_shutdown(cx)
104 }
105
106 fn poll_write_vectored(
107 self: Pin<&mut Self>,
108 cx: &mut Context<'_>,
109 bufs: &[io::IoSlice<'_>],
110 ) -> Poll<Result<usize, io::Error>> {
111 self.project().writer.poll_write_vectored(cx, bufs)
112 }
113
114 fn is_write_vectored(&self) -> bool {
115 self.writer.is_write_vectored()
116 }
117}
118