pub use tokio::io::{AsyncRead, AsyncWrite, Interest, ReadBuf, Ready};
use core::{
future::Future,
pin::Pin,
task::{Context, Poll, ready},
};
use std::io;
pub trait AsyncIo: io::Read + io::Write + Unpin {
fn ready(&mut self, interest: Interest) -> impl Future<Output = io::Result<Ready>> + Send;
fn poll_ready(&mut self, interest: Interest, cx: &mut Context<'_>) -> Poll<io::Result<Ready>>;
fn is_vectored_write(&self) -> bool;
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>>;
}
pub trait AsyncIoDyn: io::Read + io::Write + Unpin {
fn ready(&mut self, interest: Interest) -> Pin<Box<dyn Future<Output = io::Result<Ready>> + Send + '_>>;
fn poll_ready(&mut self, interest: Interest, cx: &mut Context<'_>) -> Poll<io::Result<Ready>>;
fn is_vectored_write(&self) -> bool;
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>>;
}
impl<Io> AsyncIoDyn for Io
where
Io: AsyncIo,
{
#[inline]
fn ready(&mut self, interest: Interest) -> Pin<Box<dyn Future<Output = io::Result<Ready>> + Send + '_>> {
Box::pin(AsyncIo::ready(self, interest))
}
#[inline]
fn poll_ready(&mut self, interest: Interest, cx: &mut Context<'_>) -> Poll<io::Result<Ready>> {
AsyncIo::poll_ready(self, interest, cx)
}
fn is_vectored_write(&self) -> bool {
AsyncIo::is_vectored_write(self)
}
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
AsyncIo::poll_shutdown(self, cx)
}
}
impl<IoDyn> AsyncIo for Box<IoDyn>
where
IoDyn: AsyncIoDyn + Send + ?Sized,
{
#[inline]
async fn ready(&mut self, interest: Interest) -> io::Result<Ready> {
AsyncIoDyn::ready(&mut **self, interest).await
}
#[inline]
fn poll_ready(&mut self, interest: Interest, cx: &mut Context<'_>) -> Poll<io::Result<Ready>> {
AsyncIoDyn::poll_ready(&mut **self, interest, cx)
}
fn is_vectored_write(&self) -> bool {
AsyncIoDyn::is_vectored_write(&**self)
}
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
AsyncIoDyn::poll_shutdown(Pin::new(&mut **self.get_mut()), cx)
}
}
fn _assert_object_safe(mut io: Box<dyn AsyncIoDyn>) {
let _ = io.read(&mut []);
let _ = io.write(&[]);
}
pub struct PollIoAdapter<T>(pub T)
where
T: AsyncIo;
impl<T> AsyncRead for PollIoAdapter<T>
where
T: AsyncIo,
{
fn poll_read(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>) -> Poll<io::Result<()>> {
let this = self.get_mut();
loop {
ready!(this.0.poll_ready(Interest::READABLE, cx))?;
match io::Read::read(&mut this.0, buf.initialize_unfilled()) {
Ok(n) => {
buf.advance(n);
return Poll::Ready(Ok(()));
}
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {}
Err(e) => return Poll::Ready(Err(e)),
}
}
}
}
impl<T> AsyncWrite for PollIoAdapter<T>
where
T: AsyncIo,
{
fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<io::Result<usize>> {
let this = self.get_mut();
loop {
ready!(this.0.poll_ready(Interest::WRITABLE, cx))?;
match io::Write::write(&mut this.0, buf) {
Ok(n) => return Poll::Ready(Ok(n)),
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {}
Err(e) => return Poll::Ready(Err(e)),
}
}
}
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
let this = self.get_mut();
loop {
ready!(this.0.poll_ready(Interest::WRITABLE, cx))?;
match io::Write::flush(&mut this.0) {
Ok(_) => return Poll::Ready(Ok(())),
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {}
Err(e) => return Poll::Ready(Err(e)),
}
}
}
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
AsyncIo::poll_shutdown(Pin::new(&mut self.get_mut().0), cx)
}
fn poll_write_vectored(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
bufs: &[io::IoSlice<'_>],
) -> Poll<io::Result<usize>> {
let this = self.get_mut();
loop {
ready!(this.0.poll_ready(Interest::WRITABLE, cx))?;
match io::Write::write_vectored(&mut this.0, bufs) {
Ok(n) => return Poll::Ready(Ok(n)),
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {}
Err(e) => return Poll::Ready(Err(e)),
}
}
}
fn is_write_vectored(&self) -> bool {
self.0.is_vectored_write()
}
}
impl<Io> AsyncIo for PollIoAdapter<Io>
where
Io: AsyncIo,
{
#[inline(always)]
fn ready(&mut self, interest: Interest) -> impl Future<Output = io::Result<Ready>> + Send {
self.0.ready(interest)
}
#[inline(always)]
fn poll_ready(&mut self, interest: Interest, cx: &mut Context<'_>) -> Poll<io::Result<Ready>> {
self.0.poll_ready(interest, cx)
}
fn is_vectored_write(&self) -> bool {
self.0.is_vectored_write()
}
fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
Pin::new(&mut self.get_mut().0).poll_shutdown(cx)
}
}
impl<Io> io::Write for PollIoAdapter<Io>
where
Io: AsyncIo,
{
#[inline(always)]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.0.write(buf)
}
#[inline(always)]
fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
self.0.write_vectored(bufs)
}
#[inline(always)]
fn flush(&mut self) -> io::Result<()> {
self.0.flush()
}
}
impl<Io> io::Read for PollIoAdapter<Io>
where
Io: AsyncIo,
{
#[inline(always)]
fn read(&mut self, buf: &mut [u8]) -> ::std::io::Result<usize> {
self.0.read(buf)
}
}