extern crate std;
use core::pin::Pin;
use core::task::{Context, Poll};
pub trait AsyncRead {
fn poll_read(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<std::io::Result<usize>>;
}
pub trait AsyncWrite {
fn poll_write(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<std::io::Result<usize>>;
fn poll_flush(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<std::io::Result<()>>;
}
pub async fn read_exact<R: AsyncRead + Unpin>(
reader: &mut R,
buf: &mut [u8],
) -> std::io::Result<()> {
let mut filled = 0;
while filled < buf.len() {
let n = core::future::poll_fn(|cx| {
Pin::new(&mut *reader).poll_read(cx, &mut buf[filled..])
})
.await?;
if n == 0 {
return Err(std::io::Error::new(
std::io::ErrorKind::UnexpectedEof,
"unexpected end of stream",
));
}
filled += n;
}
Ok(())
}
pub async fn write_all<W: AsyncWrite + Unpin>(
writer: &mut W,
buf: &[u8],
) -> std::io::Result<()> {
let mut written = 0;
while written < buf.len() {
let n = core::future::poll_fn(|cx| {
Pin::new(&mut *writer).poll_write(cx, &buf[written..])
})
.await?;
if n == 0 {
return Err(std::io::Error::new(
std::io::ErrorKind::WriteZero,
"write returned 0",
));
}
written += n;
}
Ok(())
}
pub async fn flush<W: AsyncWrite + Unpin>(writer: &mut W) -> std::io::Result<()> {
core::future::poll_fn(|cx| Pin::new(&mut *writer).poll_flush(cx)).await
}
impl<T: AsRef<[u8]> + Unpin> AsyncRead for std::io::Cursor<T> {
fn poll_read(
self: Pin<&mut Self>,
_cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<std::io::Result<usize>> {
Poll::Ready(std::io::Read::read(self.get_mut(), buf))
}
}
impl<W: AsyncWrite + Unpin + ?Sized> AsyncWrite for &mut W {
fn poll_write(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<std::io::Result<usize>> {
Pin::new(&mut **self.get_mut()).poll_write(cx, buf)
}
fn poll_flush(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<std::io::Result<()>> {
Pin::new(&mut **self.get_mut()).poll_flush(cx)
}
}
impl AsyncWrite for alloc::vec::Vec<u8> {
fn poll_write(
self: Pin<&mut Self>,
_cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<std::io::Result<usize>> {
Poll::Ready(std::io::Write::write(self.get_mut(), buf))
}
fn poll_flush(
self: Pin<&mut Self>,
_cx: &mut Context<'_>,
) -> Poll<std::io::Result<()>> {
Poll::Ready(std::io::Write::flush(self.get_mut()))
}
}