1use futures_core::future::Future;
2use futures_core::task::{Context, Poll};
3use futures_io::AsyncBufRead;
4use std::io;
5use std::pin::Pin;
6
7/// Future for the [`fill_buf`](super::AsyncBufReadExt::fill_buf) method.
8#[derive(Debug)]
9#[must_use = "futures do nothing unless you `.await` or poll them"]
10pub struct FillBuf<'a, R: ?Sized> {
11 reader: Option<&'a mut R>,
12}
13
14impl<R: ?Sized> Unpin for FillBuf<'_, R> {}
15
16impl<'a, R: AsyncBufRead + ?Sized + Unpin> FillBuf<'a, R> {
17 pub(super) fn new(reader: &'a mut R) -> Self {
18 Self { reader: Some(reader) }
19 }
20}
21
22impl<'a, R> Future for FillBuf<'a, R>
23where
24 R: AsyncBufRead + ?Sized + Unpin,
25{
26 type Output = io::Result<&'a [u8]>;
27
28 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
29 let this = &mut *self;
30 let reader = this.reader.take().expect("Polled FillBuf after completion");
31
32 match Pin::new(&mut *reader).poll_fill_buf(cx) {
33 // With polonius it is possible to remove this inner match and just have the correct
34 // lifetime of the reference inferred based on which branch is taken
35 Poll::Ready(Ok(_)) => match Pin::new(reader).poll_fill_buf(cx) {
36 Poll::Ready(Ok(slice)) => Poll::Ready(Ok(slice)),
37 Poll::Ready(Err(err)) => {
38 unreachable!("reader indicated readiness but then returned an error: {:?}", err)
39 }
40 Poll::Pending => {
41 unreachable!("reader indicated readiness but then returned pending")
42 }
43 },
44 Poll::Ready(Err(err)) => Poll::Ready(Err(err)),
45 Poll::Pending => {
46 this.reader = Some(reader);
47 Poll::Pending
48 }
49 }
50 }
51}
52