#![doc = include_str!("../README.md")]
mod implementations;
mod util;
use thiserror::Error;
use zerocopy::{FromBytes, Immutable, IntoBytes, Unaligned};
pub use assert_layout::assert_layout;
pub use cuisiner_derive::Cuisiner;
pub use zerocopy::{self, BigEndian, ByteOrder, LittleEndian, NativeEndian, NetworkEndian};
pub use self::util::*;
pub trait Cuisiner: Sized {
type Raw<B: ByteOrder>: FromBytes + IntoBytes + Immutable + Unaligned;
fn try_from_raw<B: ByteOrder>(raw: Self::Raw<B>) -> Result<Self, CuisinerError>;
fn try_to_raw<B: ByteOrder>(self) -> Result<Self::Raw<B>, CuisinerError>;
fn from_bytes<B: ByteOrder>(bytes: &[u8]) -> Result<Self, CuisinerError> {
let (raw, _) =
Self::Raw::<B>::read_from_prefix(bytes).map_err(|_| CuisinerError::SizeError {
required: std::mem::size_of::<Self::Raw<B>>(),
found: bytes.len(),
})?;
Self::try_from_raw(raw)
}
fn to_bytes<B: ByteOrder>(self) -> Result<Vec<u8>, CuisinerError> {
Ok(self.try_to_raw::<B>()?.as_bytes().to_vec())
}
}
#[derive(Debug, Error)]
pub enum CuisinerError {
#[error("zero encountered in an unexpected location")]
Zero,
#[error(
"incorrect buffer size for serialising or deserialising (required {required}, found {found})"
)]
SizeError { required: usize, found: usize },
#[error("error when validating: {0}")]
Validation(String),
}