use core::pin::Pin;
use core::task::{Context, Poll};
use std::io;
use std::net::TcpStream;
#[cfg(unix)]
use std::os::unix::net::UnixStream;
use std::sync::Arc;
use futures_io::{AsyncRead, AsyncWrite};
use super::split::{OwnedReadHalf, OwnedWriteHalf, ReadHalf, WriteHalf};
use crate::io::{Handle, Interest, Ready};
macro_rules! read_side {
($($ty:ty),* $(,)?) => {$(
impl Handle<$ty> {
pub async fn read_owned(&self, buf: Vec<u8>) -> (io::Result<usize>, Vec<u8>) {
self.source().read_owned(buf).await
}
pub async fn readable(&self) -> io::Result<()> {
core::future::poll_fn(|cx| self.poll_read_ready(cx)).await
}
pub fn poll_read_ready(&self, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
self.source().poll_read_ready(cx).map(|r| r.map(drop))
}
pub fn try_read(&self, buf: &mut [u8]) -> io::Result<usize> {
super::at_once(|cx| self.source().poll_read(cx, buf, false))
}
pub fn try_read_vectored(&self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> {
super::at_once(|cx| self.source().poll_read_vectored(cx, bufs))
}
}
impl AsyncRead for &Handle<$ty> {
fn poll_read(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<io::Result<usize>> {
self.source().poll_read(cx, buf, false)
}
fn poll_read_vectored(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
bufs: &mut [io::IoSliceMut<'_>],
) -> Poll<io::Result<usize>> {
self.source().poll_read_vectored(cx, bufs)
}
}
impl AsyncRead for Handle<$ty> {
fn poll_read(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<io::Result<usize>> {
self.source().poll_read(cx, buf, false)
}
fn poll_read_vectored(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
bufs: &mut [io::IoSliceMut<'_>],
) -> Poll<io::Result<usize>> {
self.source().poll_read_vectored(cx, bufs)
}
}
)*};
}
macro_rules! write_side {
($($ty:ty),* $(,)?) => {$(
impl Handle<$ty> {
pub async fn write_owned(&self, buf: Vec<u8>) -> (io::Result<usize>, Vec<u8>) {
self.source().write_owned(buf).await
}
pub async fn writable(&self) -> io::Result<()> {
core::future::poll_fn(|cx| self.poll_write_ready(cx)).await
}
pub fn poll_write_ready(&self, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
self.source().poll_write_ready(cx).map(|r| r.map(drop))
}
pub fn try_write(&self, buf: &[u8]) -> io::Result<usize> {
super::at_once(|cx| self.source().poll_write(cx, buf))
}
pub fn try_write_vectored(&self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> {
super::at_once(|cx| self.source().poll_write_vectored(cx, bufs))
}
}
impl AsyncWrite for &Handle<$ty> {
fn poll_write(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<io::Result<usize>> {
self.source().poll_write(cx, buf)
}
fn poll_write_vectored(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
bufs: &[io::IoSlice<'_>],
) -> Poll<io::Result<usize>> {
self.source().poll_write_vectored(cx, bufs)
}
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
self.source().poll_flush(cx)
}
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
self.source().poll_close(cx)
}
}
impl AsyncWrite for Handle<$ty> {
fn poll_write(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<io::Result<usize>> {
self.source().poll_write(cx, buf)
}
fn poll_write_vectored(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
bufs: &[io::IoSlice<'_>],
) -> Poll<io::Result<usize>> {
self.source().poll_write_vectored(cx, bufs)
}
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
self.source().poll_flush(cx)
}
fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
self.source().poll_close(cx)
}
}
)*};
}
macro_rules! stream_io {
($($ty:ty),* $(,)?) => {$(
read_side!($ty);
write_side!($ty);
impl Handle<$ty> {
pub fn split(&self) -> (ReadHalf<'_, $ty>, WriteHalf<'_, $ty>) {
(ReadHalf(self), WriteHalf(self))
}
pub fn into_split(self) -> (OwnedReadHalf<$ty>, OwnedWriteHalf<$ty>) {
let both = Arc::new(self);
(OwnedReadHalf(Arc::clone(&both)), OwnedWriteHalf(both))
}
pub async fn ready(&self, interest: Interest) -> io::Result<Ready> {
core::future::poll_fn(|cx| super::poll_ready(self.source(), cx, interest)).await
}
}
)*};
}
stream_io!(TcpStream);
#[cfg(unix)]
stream_io!(UnixStream);
#[cfg(unix)]
read_side!(std::io::PipeReader);
#[cfg(unix)]
write_side!(std::io::PipeWriter);