1use std::{
2 borrow::Cow,
3 io,
4 mem::MaybeUninit,
5 pin::Pin,
6 task::{Context, Poll, ready},
7};
8
9use compio::{
10 io::{AsyncRead, AsyncWrite, util::Splittable},
11 tls::{MaybeTlsStream, TlsStream},
12};
13use send_wrapper::SendWrapper;
14
15#[derive(Debug)]
17pub struct HyperStream<S: Splittable>(SendWrapper<MaybeTlsStream<S>>);
18
19impl<S: Splittable> HyperStream<S> {
20 pub fn new_plain(s: S) -> Self {
22 Self(SendWrapper::new(MaybeTlsStream::new_plain(s)))
23 }
24
25 pub fn new_tls(s: TlsStream<S>) -> Self {
27 Self(SendWrapper::new(MaybeTlsStream::new_tls(s)))
28 }
29
30 pub fn is_tls(&self) -> bool {
32 self.0.is_tls()
33 }
34}
35
36impl<S: Splittable + 'static> HyperStream<S>
37where
38 S::ReadHalf: AsyncRead + Unpin,
39 S::WriteHalf: AsyncWrite + Unpin,
40{
41 pub fn negotiated_alpn(&self) -> Option<Cow<'_, [u8]>> {
43 self.0.negotiated_alpn()
44 }
45}
46
47impl<S: Splittable + 'static> hyper::rt::Read for HyperStream<S>
48where
49 S::ReadHalf: AsyncRead + Unpin,
50 S::WriteHalf: AsyncWrite + Unpin,
51{
52 fn poll_read(
53 mut self: Pin<&mut Self>,
54 cx: &mut Context<'_>,
55 mut buf: hyper::rt::ReadBufCursor<'_>,
56 ) -> Poll<io::Result<()>> {
57 let uninit = unsafe { buf.as_mut() };
58 uninit.fill(MaybeUninit::new(0));
59 let res = ready!(futures_util::AsyncRead::poll_read(
60 Pin::new(&mut *self.0),
61 cx,
62 unsafe { uninit.assume_init_mut() }
63 ))?;
64 unsafe { buf.advance(res) };
65 Poll::Ready(Ok(()))
66 }
67}
68
69impl<S: Splittable + 'static> futures_util::AsyncRead for HyperStream<S>
70where
71 S::ReadHalf: AsyncRead + Unpin,
72 S::WriteHalf: AsyncWrite + Unpin,
73{
74 fn poll_read(
75 mut self: Pin<&mut Self>,
76 cx: &mut Context<'_>,
77 buf: &mut [u8],
78 ) -> Poll<io::Result<usize>> {
79 futures_util::AsyncRead::poll_read(Pin::new(&mut *self.0), cx, buf)
80 }
81
82 fn poll_read_vectored(
83 mut self: Pin<&mut Self>,
84 cx: &mut Context<'_>,
85 bufs: &mut [io::IoSliceMut<'_>],
86 ) -> Poll<io::Result<usize>> {
87 futures_util::AsyncRead::poll_read_vectored(Pin::new(&mut *self.0), cx, bufs)
88 }
89}
90
91impl<S: Splittable + 'static> hyper::rt::Write for HyperStream<S>
92where
93 S::ReadHalf: AsyncRead + Unpin,
94 S::WriteHalf: AsyncWrite + Unpin,
95{
96 fn poll_write(
97 mut self: Pin<&mut Self>,
98 cx: &mut Context<'_>,
99 buf: &[u8],
100 ) -> Poll<io::Result<usize>> {
101 futures_util::AsyncWrite::poll_write(Pin::new(&mut *self.0), cx, buf)
102 }
103
104 fn poll_write_vectored(
105 mut self: Pin<&mut Self>,
106 cx: &mut Context<'_>,
107 bufs: &[io::IoSlice<'_>],
108 ) -> Poll<io::Result<usize>> {
109 futures_util::AsyncWrite::poll_write_vectored(Pin::new(&mut *self.0), cx, bufs)
110 }
111
112 fn is_write_vectored(&self) -> bool {
113 true
114 }
115
116 fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
117 futures_util::AsyncWrite::poll_flush(Pin::new(&mut *self.0), cx)
118 }
119
120 fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
121 futures_util::AsyncWrite::poll_close(Pin::new(&mut *self.0), cx)
122 }
123}
124
125impl<S: Splittable + 'static> futures_util::AsyncWrite for HyperStream<S>
126where
127 S::ReadHalf: AsyncRead + Unpin,
128 S::WriteHalf: AsyncWrite + Unpin,
129{
130 fn poll_write(
131 mut self: Pin<&mut Self>,
132 cx: &mut Context<'_>,
133 buf: &[u8],
134 ) -> Poll<io::Result<usize>> {
135 futures_util::AsyncWrite::poll_write(Pin::new(&mut *self.0), cx, buf)
136 }
137
138 fn poll_write_vectored(
139 mut self: Pin<&mut Self>,
140 cx: &mut Context<'_>,
141 bufs: &[io::IoSlice<'_>],
142 ) -> Poll<io::Result<usize>> {
143 futures_util::AsyncWrite::poll_write_vectored(Pin::new(&mut *self.0), cx, bufs)
144 }
145
146 fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
147 futures_util::AsyncWrite::poll_flush(Pin::new(&mut *self.0), cx)
148 }
149
150 fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
151 futures_util::AsyncWrite::poll_close(Pin::new(&mut *self.0), cx)
152 }
153}