mod defaults;
mod header;
pub use header::*;
pub type DefaultPayloadContext = ();
pub const fn default_payload_context() -> DefaultPayloadContext {}
pub trait PayloadSchema {
type Context<'a>;
}
pub enum EncodedPayload<'a> {
Borrowed(&'a [u8]),
Owned(Vec<u8>),
}
impl EncodedPayload<'_> {
pub fn as_slice(&self) -> &[u8] {
match self {
Self::Borrowed(bytes) => bytes,
Self::Owned(bytes) => bytes.as_slice(),
}
}
pub fn len(&self) -> usize {
self.as_slice().len()
}
pub fn is_empty(&self) -> bool {
self.as_slice().is_empty()
}
}
pub trait PayloadHooks {
fn before_encode(&mut self) -> std::io::Result<()> {
Ok(())
}
fn after_decode(&mut self) -> std::io::Result<()> {
Ok(())
}
}
pub trait PayloadEncode: PayloadHooks + PayloadSchema {
fn encode(&self, ctx: &mut Self::Context<'_>) -> std::io::Result<Vec<u8>>;
}
pub trait PayloadEncodeReferred: PayloadSchema {
fn encode(&self, ctx: &mut Self::Context<'_>) -> std::io::Result<Option<&[u8]>>;
}
pub trait PayloadEncoded: PayloadEncode + PayloadEncodeReferred {
fn encoded(&self, ctx: &mut Self::Context<'_>) -> std::io::Result<EncodedPayload<'_>> {
if let Some(bytes) = PayloadEncodeReferred::encode(self, ctx)? {
Ok(EncodedPayload::Borrowed(bytes))
} else {
Ok(EncodedPayload::Owned(PayloadEncode::encode(self, ctx)?))
}
}
}
impl<T> PayloadEncoded for T where T: PayloadEncode + PayloadEncodeReferred {}
pub trait PayloadDecode<T>: PayloadHooks + PayloadSchema {
fn decode(buf: &[u8], ctx: &mut Self::Context<'_>) -> std::io::Result<T>;
}