1 | use crate::io::{AsyncRead, ReadBuf}; |
2 | |
3 | use pin_project_lite::pin_project; |
4 | use std::future::Future; |
5 | use std::io; |
6 | use std::marker::PhantomPinned; |
7 | use std::marker::Unpin; |
8 | use std::pin::Pin; |
9 | use std::task::{Context, Poll}; |
10 | |
11 | /// Tries to read some bytes directly into the given `buf` in asynchronous |
12 | /// manner, returning a future type. |
13 | /// |
14 | /// The returned future will resolve to both the I/O stream and the buffer |
15 | /// as well as the number of bytes read once the read operation is completed. |
16 | pub(crate) fn read<'a, R>(reader: &'a mut R, buf: &'a mut [u8]) -> Read<'a, R> |
17 | where |
18 | R: AsyncRead + Unpin + ?Sized, |
19 | { |
20 | Read { |
21 | reader, |
22 | buf, |
23 | _pin: PhantomPinned, |
24 | } |
25 | } |
26 | |
27 | pin_project! { |
28 | /// A future which can be used to easily read available number of bytes to fill |
29 | /// a buffer. |
30 | /// |
31 | /// Created by the [`read`] function. |
32 | #[derive(Debug)] |
33 | #[must_use = "futures do nothing unless you `.await` or poll them" ] |
34 | pub struct Read<'a, R: ?Sized> { |
35 | reader: &'a mut R, |
36 | buf: &'a mut [u8], |
37 | // Make this future `!Unpin` for compatibility with async trait methods. |
38 | #[pin] |
39 | _pin: PhantomPinned, |
40 | } |
41 | } |
42 | |
43 | impl<R> Future for Read<'_, R> |
44 | where |
45 | R: AsyncRead + Unpin + ?Sized, |
46 | { |
47 | type Output = io::Result<usize>; |
48 | |
49 | fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<usize>> { |
50 | let me: Projection<'_, '_, R> = self.project(); |
51 | let mut buf: ReadBuf<'_> = ReadBuf::new(me.buf); |
52 | ready!(Pin::new(me.reader).poll_read(cx, &mut buf))?; |
53 | Poll::Ready(Ok(buf.filled().len())) |
54 | } |
55 | } |
56 | |