pub trait WireEncode {
fn required_size(&self) -> usize;
fn wire_valid(&self) -> Result<(), InvalidStructureError>;
unsafe fn encode_unchecked(&self, buf: &mut [u8]) -> usize;
fn encode(&self, buf: &mut [u8]) -> Result<usize, EncodeError> {
self.wire_valid()?;
let required_size = self.required_size();
if buf.len() < required_size {
return Err(EncodeError::BufferTooSmall(required_size));
}
unsafe { Ok(self.encode_unchecked(buf)) }
}
fn encode_to_vec(&self) -> Result<Vec<u8>, EncodeError> {
let mut buf = vec![0u8; self.required_size()];
self.encode(&mut buf)?;
Ok(buf)
}
}
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
pub enum EncodeError {
#[error(transparent)]
InvalidStructure(#[from] InvalidStructureError),
#[error("buffer too small: required {0}")]
BufferTooSmall(usize),
}
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
#[error("cannot encode structure: {0}")]
pub struct InvalidStructureError(&'static str);
impl From<&'static str> for InvalidStructureError {
fn from(s: &'static str) -> Self {
InvalidStructureError(s)
}
}