1#[doc = include_str!("../README.md")]
2
3use std::{
4 pin::Pin,
5 task::{Context, Poll},
6};
7
8use futures::{AsyncRead, AsyncWrite};
9use pin_project::pin_project;
10
11#[pin_project]
13pub struct AsyncReadWriteCompat<T: AsyncRead + AsyncWrite> {
14 #[pin]
15 inner: T,
16}
17
18impl<T: AsyncRead + AsyncWrite> AsyncReadWriteCompat<T> {
19 pub fn new(inner: T) -> Self {
21 Self { inner }
22 }
23
24 pub fn into_inner(self) -> T {
26 self.inner
27 }
28}
29
30impl<T: AsyncRead + AsyncWrite> hyper::rt::Read for AsyncReadWriteCompat<T> {
31 fn poll_read(
32 self: Pin<&mut Self>,
33 cx: &mut Context<'_>,
34 mut buf: hyper::rt::ReadBufCursor<'_>,
35 ) -> Poll<Result<(), std::io::Error>> {
36 let buf_slice: &mut [u8] = unsafe { std::mem::transmute(buf.as_mut()) };
37 match self.project().inner.poll_read(cx, buf_slice) {
38 Poll::Ready(bytes_read) => {
39 let bytes_read = bytes_read?;
40 unsafe {
41 buf.advance(bytes_read);
42 }
43 Poll::Ready(Ok(()))
44 }
45 Poll::Pending => Poll::Pending,
46 }
47 }
48}
49
50impl<T: AsyncRead + AsyncWrite> hyper::rt::Write for AsyncReadWriteCompat<T> {
51 fn poll_write(
52 self: Pin<&mut Self>,
53 cx: &mut Context<'_>,
54 buf: &[u8],
55 ) -> Poll<Result<usize, std::io::Error>> {
56 self.project().inner.poll_write(cx, buf)
57 }
58
59 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), std::io::Error>> {
60 self.project().inner.poll_flush(cx)
61 }
62
63 fn poll_shutdown(
64 self: Pin<&mut Self>,
65 cx: &mut Context<'_>,
66 ) -> Poll<Result<(), std::io::Error>> {
67 self.project().inner.poll_close(cx)
68 }
69}