use std::{time::Duration, net::SocketAddr, fmt};
pub trait ReadOnce {
fn read(self, buf: &mut [u8]) -> IoResult;
}
pub trait WriteOnce {
fn write(self, data: &[u8]) -> IoResult;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[must_use = "need to know how many bytes was actually read or written"]
pub enum IoResult {
Closed,
Done { length: usize, will_close: bool },
}
pub struct Proposal<R, W, Ext, Rng> {
pub rng: Rng,
pub elapsed: Duration,
pub kind: ProposalKind<R, W, Ext>,
}
impl<R, W, Ext, Rng> Proposal<R, W, Ext, Rng> {
pub fn custom(rng: Rng, ext: Ext) -> Self {
Proposal {
rng,
elapsed: Duration::ZERO,
kind: ProposalKind::Custom(ext),
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ConnectionId {
pub poll_id: u16,
pub token: u16,
}
pub enum ProposalKind<R, W, Ext> {
Wake,
Idle,
Connection {
addr: SocketAddr,
incoming: bool,
id: ConnectionId,
},
OnReadable(ConnectionId, R),
OnWritable(ConnectionId, W),
Custom(Ext),
}
impl<R, W, Ext, Rng> fmt::Display for Proposal<R, W, Ext, Rng>
where
Ext: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "elapsed: {:?}, {}", self.elapsed, self.kind)
}
}
impl<R, W, Ext> fmt::Display for ProposalKind<R, W, Ext>
where
Ext: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ProposalKind::Wake => write!(f, "wake"),
ProposalKind::Idle => write!(f, "idle..."),
ProposalKind::Connection { addr, incoming, id } => {
if *incoming {
write!(f, "new incoming connection: {}, addr: {}", id, addr)
} else {
write!(f, "new outgoing connection: {}, addr: {}", id, addr)
}
},
ProposalKind::OnReadable(id, _) => write!(f, "local peer can read from {}", id),
ProposalKind::OnWritable(id, _) => write!(f, "local peer can write to {}", id),
ProposalKind::Custom(ext) => write!(f, "{}", ext),
}
}
}
impl fmt::Display for ConnectionId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:04x}.{:04x}", self.poll_id, self.token)
}
}