use std::ops::DerefMut;
use std::pin::Pin;
use std::task::{Context, Poll};
pub use self::buf_read_ext::AsyncBufReadExt;
pub use self::buf_reader::AsyncBufReader;
pub use self::passthrough::AsyncBufPassthrough;
mod buf_read_ext;
mod buf_reader;
mod io;
mod passthrough;
mod peek;
pub trait AsyncBufRead: io::AsyncRead {
fn eof(self: Pin<&Self>) -> bool;
fn buf(self: Pin<&Self>) -> &[u8];
fn poll_fill_buf<'a>(
self: Pin<&'a mut Self>,
cx: &mut Context<'_>,
amt: usize,
) -> Poll<io::Result<&'a [u8]>>;
fn consume(self: Pin<&mut Self>, amt: usize);
}
macro_rules! deref_async_buf_read {
() => {
fn eof(self: Pin<&Self>) -> bool {
Pin::new(&**self.get_ref()).eof()
}
fn buf(self: Pin<&Self>) -> &[u8] {
Pin::new(&**self.get_ref()).buf()
}
fn poll_fill_buf(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
amt: usize,
) -> Poll<io::Result<&[u8]>> {
Pin::new(&mut **self.get_mut()).poll_fill_buf(cx, amt)
}
fn consume(mut self: Pin<&mut Self>, amt: usize) {
Pin::new(&mut **self).consume(amt)
}
};
}
impl<T: ?Sized + AsyncBufRead + Unpin> AsyncBufRead for Box<T> {
deref_async_buf_read!();
}
impl<T: ?Sized + AsyncBufRead + Unpin> AsyncBufRead for &mut T {
deref_async_buf_read!();
}
impl<P> AsyncBufRead for Pin<P>
where
P: DerefMut + Unpin,
P::Target: AsyncBufRead,
{
fn eof(self: Pin<&Self>) -> bool {
self.get_ref().as_ref().eof()
}
fn buf(self: Pin<&Self>) -> &[u8] {
self.get_ref().as_ref().buf()
}
fn poll_fill_buf(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
amt: usize,
) -> Poll<io::Result<&[u8]>> {
self.get_mut().as_mut().poll_fill_buf(cx, amt)
}
fn consume(self: Pin<&mut Self>, amt: usize) {
self.get_mut().as_mut().consume(amt);
}
}
impl AsyncBufRead for &[u8] {
fn eof(self: Pin<&Self>) -> bool {
false
}
fn buf(self: Pin<&Self>) -> &[u8] {
self.get_ref()
}
fn poll_fill_buf(
self: Pin<&mut Self>,
_cx: &mut Context<'_>,
amt: usize,
) -> Poll<io::Result<&[u8]>> {
let amt = std::cmp::min(self.len(), amt);
Poll::Ready(Ok(&self[..amt]))
}
fn consume(mut self: Pin<&mut Self>, amt: usize) {
*self = &self[amt..];
}
}