use std::future::Future;
use std::io;
use std::marker::PhantomPinned;
use std::pin::Pin;
use std::task::{Context, Poll};
use pin_project_lite::pin_project;
use crate::AsyncBufRead;
pub(crate) fn peek<'a, R>(reader: &'a mut R, amt: usize) -> Peek<'a, R>
where
R: AsyncBufRead + Unpin + ?Sized,
{
Peek {
reader: Some(reader),
amt,
_pin: PhantomPinned,
}
}
pin_project! {
#[derive(Debug)]
#[must_use = "futures do nothing unless you `.await` or poll them"]
pub struct Peek<'a, R: ?Sized> {
reader: Option<&'a mut R>,
amt: usize,
#[pin]
_pin: PhantomPinned,
}
}
impl<'a, R> Future for Peek<'a, R>
where
R: AsyncBufRead + Unpin + ?Sized,
{
type Output = io::Result<&'a [u8]>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let me = self.project();
let reader = me.reader.take().expect("Polled after completion.");
match Pin::new(&mut *reader).poll_fill_buf(cx, *me.amt) {
Poll::Ready(Ok(slice)) => unsafe {
let slice = std::mem::transmute::<&[u8], &'a [u8]>(slice);
Poll::Ready(Ok(slice))
},
Poll::Ready(Err(err)) => Poll::Ready(Err(err)),
Poll::Pending => {
*me.reader = Some(reader);
Poll::Pending
}
}
}
}