use std::fmt::Arguments;
use std::io::{self, Read, Write};
pub trait Stream: Read + Write {}
impl<S> Stream for S where S: Read + Write {}
pub struct ReadWritePair<R, W>(pub R, pub W)
where
R: Read,
W: Write;
impl<R, W> Read for ReadWritePair<R, W>
where
R: Read,
W: Write,
{
#[inline(always)]
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.0.read(buf)
}
#[inline(always)]
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
self.0.read_to_end(buf)
}
#[inline(always)]
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
self.0.read_to_string(buf)
}
#[inline(always)]
fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> {
self.0.read_exact(buf)
}
}
impl<R, W> Write for ReadWritePair<R, W>
where
R: Read,
W: Write,
{
#[inline(always)]
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.1.write(buf)
}
#[inline(always)]
fn flush(&mut self) -> io::Result<()> {
self.1.flush()
}
#[inline(always)]
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
self.1.write_all(buf)
}
#[inline(always)]
fn write_fmt(&mut self, fmt: Arguments) -> io::Result<()> {
self.1.write_fmt(fmt)
}
}
#[cfg(feature = "async")]
pub mod r#async {
pub use super::ReadWritePair;
use futures::Poll;
use std::io::{self, Read, Write};
pub use tokio_io::io::{ReadHalf, WriteHalf};
pub use tokio_io::{AsyncRead, AsyncWrite};
pub use tokio_tcp::TcpStream;
pub trait Stream: AsyncRead + AsyncWrite {}
impl<S> Stream for S where S: AsyncRead + AsyncWrite {}
impl<R, W> AsyncRead for ReadWritePair<R, W>
where
R: AsyncRead,
W: Write,
{
}
impl<R, W> AsyncWrite for ReadWritePair<R, W>
where
W: AsyncWrite,
R: Read,
{
fn shutdown(&mut self) -> Poll<(), io::Error> {
self.1.shutdown()
}
}
}
#[cfg(feature = "sync")]
pub mod sync {
pub use super::ReadWritePair;
#[cfg(feature = "sync-ssl")]
pub use native_tls::TlsStream;
use std::io::{self, Read, Write};
pub use std::net::Shutdown;
pub use std::net::TcpStream;
use std::ops::Deref;
pub use super::Stream;
pub trait NetworkStream: Read + Write + AsTcpStream {}
impl<S> NetworkStream for S where S: Read + Write + AsTcpStream {}
pub trait Splittable {
type Reader: Read;
type Writer: Write;
fn split(self) -> io::Result<(Self::Reader, Self::Writer)>;
}
impl<R, W> Splittable for ReadWritePair<R, W>
where
R: Read,
W: Write,
{
type Reader = R;
type Writer = W;
fn split(self) -> io::Result<(R, W)> {
Ok((self.0, self.1))
}
}
impl Splittable for TcpStream {
type Reader = TcpStream;
type Writer = TcpStream;
fn split(self) -> io::Result<(TcpStream, TcpStream)> {
self.try_clone().map(|s| (s, self))
}
}
pub trait AsTcpStream {
fn as_tcp(&self) -> &TcpStream;
}
impl AsTcpStream for TcpStream {
fn as_tcp(&self) -> &TcpStream {
self
}
}
#[cfg(feature = "sync-ssl")]
impl AsTcpStream for TlsStream<TcpStream> {
fn as_tcp(&self) -> &TcpStream {
self.get_ref()
}
}
impl<T> AsTcpStream for Box<T>
where
T: AsTcpStream + ?Sized,
{
fn as_tcp(&self) -> &TcpStream {
self.deref().as_tcp()
}
}
}