tokio_duplex/
lib.rs

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}