use std::net::{SocketAddr, ToSocketAddrs};
pub trait Protocol: Send + Sync + 'static {
type Listener: Listener<Self::ServerStream>;
type ServerStream: ServerStream;
type ClientStream: ClientStream;
fn bind<A>(addr: A) -> std::io::Result<Self::Listener>
where
A: ToSocketAddrs;
fn create_listener<A>(addr: A) -> std::io::Result<Self::Listener>
where
A: ToSocketAddrs,
{
let listener = Self::bind(addr)?;
log::debug!("Created and started a listener at {:?}", listener.address());
listener.set_nonblocking();
Ok(listener)
}
fn connect_to_server<A>(addr: A) -> std::io::Result<Self::ClientStream>
where
A: ToSocketAddrs,
{
let stream = Self::ClientStream::connect(addr)?;
log::debug!("Connected to a server at {:?}", stream.peer_addr());
stream.set_nonblocking();
Ok(stream)
}
}
pub trait Listener<S>: Send + Sync + 'static
where
S: ServerStream,
{
fn accept(&self) -> std::io::Result<(S, SocketAddr)>;
fn set_nonblocking(&self);
fn address(&self) -> SocketAddr;
}
pub trait ClientStream: NetworkStream {
fn connect<A>(addr: A) -> std::io::Result<Self>
where
Self: Sized,
A: ToSocketAddrs;
}
pub trait ServerStream: NetworkStream {}
pub trait NetworkStream: Send + Sync + 'static {
fn set_nonblocking(&self);
fn try_peek_exact(&self, buffer: &mut [u8]) -> std::io::Result<()>;
fn read_exact(&mut self, buffer: &mut [u8]) -> std::io::Result<()>;
fn write_all(&mut self, buffer: &[u8]) -> std::io::Result<()>;
fn peer_addr(&self) -> SocketAddr;
fn local_addr(&self) -> SocketAddr;
}