smol_hyper/rt/
futures.rs

1// MIT/Apache2 License
2
3//! Integrations with the `hyper::rt` module for `futures-io` types.
4
5use hyper::rt::ReadBufCursor;
6
7use std::io;
8use std::pin::Pin;
9use std::slice;
10use std::task::{Context, Poll};
11
12pin_project_lite::pin_project! {
13    /// This type implements [`hyper`] I/O traits for [`futures-io`] implementors.
14    #[derive(Debug, Default, Clone, Copy)]
15    pub struct FuturesIo<T: ?Sized> {
16        #[pin]
17        inner: T
18    }
19}
20
21impl<T> From<T> for FuturesIo<T> {
22    #[inline]
23    fn from(inner: T) -> Self {
24        Self { inner }
25    }
26}
27
28impl<T> FuturesIo<T> {
29    /// Wrap a type implementing I/O traits.
30    pub fn new(io: T) -> Self {
31        io.into()
32    }
33
34    /// Get the inner type.
35    pub fn into_inner(self) -> T {
36        self.inner
37    }
38}
39
40impl<T: ?Sized> FuturesIo<T> {
41    /// Get a reference to the inner type.
42    pub fn get_ref(&self) -> &T {
43        &self.inner
44    }
45
46    /// Get a mutable reference to the inner type.
47    pub fn get_mut(&mut self) -> &mut T {
48        &mut self.inner
49    }
50
51    /// Get a pinned mutable reference to the inner type.
52    pub fn get_pin_mut(self: Pin<&mut Self>) -> Pin<&mut T> {
53        self.project().inner
54    }
55}
56
57impl<T: ?Sized> AsRef<T> for FuturesIo<T> {
58    #[inline]
59    fn as_ref(&self) -> &T {
60        self.get_ref()
61    }
62}
63
64impl<T: ?Sized> AsMut<T> for FuturesIo<T> {
65    #[inline]
66    fn as_mut(&mut self) -> &mut T {
67        self.get_mut()
68    }
69}
70
71impl<T: futures_io::AsyncRead + ?Sized> hyper::rt::Read for FuturesIo<T> {
72    #[inline]
73    fn poll_read(
74        self: Pin<&mut Self>,
75        cx: &mut Context<'_>,
76        mut buf: ReadBufCursor<'_>,
77    ) -> Poll<io::Result<()>> {
78        // Fill the read buffer with initialized data.
79        let read_slice = unsafe {
80            let buffer = buf.as_mut();
81            buffer.as_mut_ptr().write_bytes(0, buffer.len());
82            slice::from_raw_parts_mut(buffer.as_mut_ptr() as *mut u8, buffer.len())
83        };
84
85        // Read bytes from the underlying source.
86        let n = match self.get_pin_mut().poll_read(cx, read_slice) {
87            Poll::Ready(Ok(n)) => n,
88            Poll::Ready(Err(e)) => return Poll::Ready(Err(e)),
89            Poll::Pending => return Poll::Pending,
90        };
91
92        // Advance the buffer.
93        unsafe {
94            buf.advance(n);
95        }
96
97        Poll::Ready(Ok(()))
98    }
99}
100
101impl<T: futures_io::AsyncWrite + ?Sized> hyper::rt::Write for FuturesIo<T> {
102    #[inline]
103    fn poll_write(
104        self: Pin<&mut Self>,
105        cx: &mut Context<'_>,
106        buf: &[u8],
107    ) -> Poll<io::Result<usize>> {
108        self.get_pin_mut().poll_write(cx, buf)
109    }
110
111    #[inline]
112    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
113        self.get_pin_mut().poll_flush(cx)
114    }
115
116    #[inline]
117    fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
118        self.get_pin_mut().poll_close(cx)
119    }
120
121    #[inline]
122    fn poll_write_vectored(
123        self: Pin<&mut Self>,
124        cx: &mut Context<'_>,
125        bufs: &[io::IoSlice<'_>],
126    ) -> Poll<io::Result<usize>> {
127        self.get_pin_mut().poll_write_vectored(cx, bufs)
128    }
129}