use crate::io::*;
use crate::stdeq::{self, AsyncIoFut};
use crate::util::PosShift;
use core::future::Future;
use core::pin::Pin;
use core::task::{Context, Poll};
#[cfg(not(mfio_assume_linear_types))]
use futures::io::AsyncRead;
use futures::io::{AsyncSeek, AsyncWrite};
use std::io::{Result, SeekFrom};
pub struct Compat<'a, Io: ?Sized> {
io: &'a Io,
#[cfg(not(mfio_assume_linear_types))]
read: Option<AsyncIoFut<'a, Io, Write, u64, &'a mut [u8]>>,
write: Option<AsyncIoFut<'a, Io, Read, u64, &'a [u8]>>,
}
pub trait FuturesCompat {
fn compat(&self) -> Compat<Self> {
Compat {
io: self,
#[cfg(not(mfio_assume_linear_types))]
read: None,
write: None,
}
}
}
impl<Io: ?Sized + stdeq::StreamPos<u64>> FuturesCompat for Io {}
#[cfg(not(mfio_assume_linear_types))]
#[cfg_attr(docsrs, doc(cfg(not(mfio_assume_linear_types))))]
impl<'a, Io: ?Sized + stdeq::AsyncRead<u64>> AsyncRead for Compat<'a, Io>
where
u64: PosShift<Io>,
{
fn poll_read(self: Pin<&mut Self>, cx: &mut Context, buf: &mut [u8]) -> Poll<Result<usize>> {
let this = unsafe { self.get_unchecked_mut() };
loop {
if let Some(read) = this.read.as_mut() {
read.sync = Some(unsafe { &mut *(buf as *mut _) });
let read = unsafe { Pin::new_unchecked(read) };
break read.poll(cx).map(|v| {
this.read = None;
v.map_err(|_| std::io::ErrorKind::Other.into())
});
} else {
let buf = unsafe { &mut *(buf as *mut _) };
this.read = Some(stdeq::AsyncRead::read(this.io, buf));
}
}
}
}
impl<'a, Io: ?Sized + stdeq::AsyncWrite<u64>> AsyncWrite for Compat<'a, Io>
where
u64: PosShift<Io>,
{
fn poll_write(self: Pin<&mut Self>, cx: &mut Context, buf: &[u8]) -> Poll<Result<usize>> {
let this = unsafe { self.get_unchecked_mut() };
loop {
if let Some(write) = this.write.as_mut() {
let write = unsafe { Pin::new_unchecked(write) };
break write.poll(cx).map(|v| {
this.write = None;
v.map_err(|_| std::io::ErrorKind::Other.into())
});
} else {
let buf = unsafe { &*(buf as *const _) };
this.write = Some(stdeq::AsyncWrite::write(this.io, buf));
}
}
}
fn poll_flush(self: Pin<&mut Self>, _: &mut Context) -> Poll<Result<()>> {
Poll::Ready(Ok(()))
}
fn poll_close(self: Pin<&mut Self>, _: &mut Context) -> Poll<Result<()>> {
Poll::Ready(Ok(()))
}
}
impl<'a, Io: ?Sized + stdeq::StreamPos<u64>> AsyncSeek for Compat<'a, Io> {
fn poll_seek(self: Pin<&mut Self>, _: &mut Context<'_>, pos: SeekFrom) -> Poll<Result<u64>> {
let this = unsafe { self.get_unchecked_mut() };
Poll::Ready(stdeq::std_seek(this.io, pos))
}
}