use std::io;
use std::future::Future;
use tokio::net::TcpStream;
pub struct ReadyFor<'a>(&'a TcpStream);
impl<'a> ReadyFor<'a>
{
pub fn wrap(tcp: &'a TcpStream) -> Self
{
Self(tcp)
}
pub fn read(self) -> impl Future<Output = io::Result<()>> + 'a
{
self.0.readable()
}
pub fn write(self) -> impl Future<Output = io::Result<()>> + 'a
{
self.0.writable()
}
}
pub struct WantedFlags
{
pub read: bool,
pub write: bool
}
pub trait Transport: Send
{
fn wants(&self, rd_hint: bool, wr_hint: bool) -> WantedFlags;
fn ready_for(&self) -> ReadyFor;
fn pre_read(&mut self) -> io::Result<bool>;
fn read(&mut self, dst: &mut [u8]) -> io::Result<usize>;
fn pre_write(&mut self) -> io::Result<()>;
fn write(&mut self, src: &[u8], zero_if_would_block: bool) -> io::Result<usize>;
fn flush(&mut self) -> io::Result<()>;
fn send_close_notify(&mut self);
}
pub struct TcpTransport
{
tcp: TcpStream
}
impl TcpTransport
{
pub fn new(stream: TcpStream) -> Self
{
Self {
tcp: stream
}
}
}
impl Transport for TcpTransport
{
fn wants(&self, rd_hint: bool, wr_hint: bool) -> WantedFlags
{
WantedFlags { read: rd_hint, write: wr_hint }
}
fn ready_for(&self) -> ReadyFor
{
ReadyFor::wrap(&self.tcp)
}
fn pre_read(&mut self) -> io::Result<bool>
{
Ok(true)
}
fn read(&mut self, dst: &mut [u8]) -> io::Result<usize>
{
self.tcp.try_read(dst)
}
fn pre_write(&mut self) -> io::Result<()>
{
Ok(())
}
fn write(&mut self, src: &[u8], zero_if_would_block: bool) -> io::Result<usize>
{
if zero_if_would_block {
match self.tcp.try_write(src) {
Ok(x) => Ok(x),
Err(err) => if err.kind() == io::ErrorKind::WouldBlock { Ok(0) } else { Err(err) }
}
} else {
self.tcp.try_write(src)
}
}
fn flush(&mut self) -> io::Result<()>
{
Ok(())
}
fn send_close_notify(&mut self)
{
}
}