1use std::io::IoSlice;
2use std::pin::Pin;
3use std::task::{Context, Poll};
4
5use pin_project_lite::pin_project;
6use tokio::io::{self, AsyncRead, AsyncWrite, ReadBuf};
7
8pin_project! {
9 #[derive(Clone, Debug)]
10 pub struct Duplex<R, W> {
11 #[pin]
12 reader: R,
13 #[pin]
14 writer: W,
15 }
16}
17
18impl<R, W> Duplex<R, W> {
19 pub fn new(reader: R, writer: W) -> Self {
20 Self { reader, writer }
21 }
22}
23
24impl<R: AsyncRead, W> AsyncRead for Duplex<R, W> {
25 fn poll_read(
26 self: Pin<&mut Self>,
27 cx: &mut Context<'_>,
28 buf: &mut ReadBuf<'_>,
29 ) -> Poll<io::Result<()>> {
30 AsyncRead::poll_read(self.project().reader, cx, buf)
31 }
32}
33
34impl<R, W: AsyncWrite> AsyncWrite for Duplex<R, W> {
35 fn poll_write(
36 self: Pin<&mut Self>,
37 cx: &mut Context<'_>,
38 buf: &[u8],
39 ) -> Poll<io::Result<usize>> {
40 AsyncWrite::poll_write(self.project().writer, cx, buf)
41 }
42
43 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
44 AsyncWrite::poll_flush(self.project().writer, cx)
45 }
46
47 fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
48 AsyncWrite::poll_shutdown(self.project().writer, cx)
49 }
50
51 fn poll_write_vectored(
52 self: Pin<&mut Self>,
53 cx: &mut Context<'_>,
54 bufs: &[IoSlice<'_>],
55 ) -> Poll<Result<usize, io::Error>> {
56 AsyncWrite::poll_write_vectored(self.project().writer, cx, bufs)
57 }
58
59 fn is_write_vectored(&self) -> bool {
60 AsyncWrite::is_write_vectored(&self.writer)
61 }
62}