use std::io::Error;
use std::io::Write;
pub trait Encodable {
fn encode(&self, write: &mut impl Write) -> Result<usize, Error>;
}
impl<T: AsRef<[u8]>> Encodable for T {
#[inline]
fn encode(&self, w: &mut impl Write) -> Result<usize, Error> {
w.write(self.as_ref())
}
}
pub trait Handler {
#[inline]
fn incoming(&mut self, _data: &impl Encodable, _write: &mut impl Write) -> Result<usize, Error> {
Ok(0)
}
#[inline]
fn outgoing(&mut self, _data: &impl Encodable, _write: &mut impl Write) -> Result<usize, Error> {
Ok(0)
}
#[inline]
fn handle(&mut self, data: &impl Encodable, w: &mut impl Write) -> Result<usize, Error> {
self.incoming(data, w).and_then(|_| self.outgoing(data, w))
}
}
#[derive(Default)]
pub struct EncoderHandler {}
impl Handler for EncoderHandler {
#[inline]
fn handle(&mut self, data: &impl Encodable, w: &mut impl Write) -> Result<usize, Error> {
data.encode(w)
}
}
#[derive(Debug)]
pub enum ChannelError {
InvalidSignature {
expected: u64,
actual: u64,
},
IncompatibleVersion {
expected: u64,
actual: u64,
},
InvalidCapacity {
capacity: u32,
msg: &'static str,
},
InvalidMaxMessageLength {
msg_len: u32,
msg: &'static str,
},
StorageNotFound {
file_name: String,
},
StorageNotReady {
file_name: String,
},
StorageAlreadyExists {
file_name: String,
},
CouldNotAccessStorage {
file_name: String,
},
MemoryMappingFailed {
reason: String,
},
AccessError {
reason: String,
},
}
#[derive(Debug)]
pub enum WriteError {
ChannelFull,
NoSpaceForRecord,
EncodingError(Error),
Wait,
}
pub trait Writer {
fn write<E: Encodable>(&mut self, data: &E) -> Result<u32, WriteError>;
fn flush(&mut self) -> Result<(), std::io::Error> {
Ok(())
}
}
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub enum ReadError {
Failed,
Timeout(u64),
Closed,
ChannelFull,
}
pub trait Reader {
fn try_read<'a>(&mut self) -> Result<Option<&'a [u8]>, ReadError>;
fn exhausted(&self) -> Option<ReadError>;
}