1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
/// The purpose of this trait is to define associated type for each lifetime for [`Schema`] trait implementations.
/// This is a workaround for lack of HRTB support for associated types.
pub trait SchemaUnpack<'a> {
/// Unpacked value type.
type Unpacked;
}
/// Trait for data schemas.
///
/// This trait requires implementation of [`SchemaUnpack`] trait for all lifetimes.
pub trait Schema: for<'a> SchemaUnpack<'a> + 'static {
/// Packed value with this schema.
/// Trivially readable from and writable to bytes.
type Packed: bytemuck::Pod;
/// Alignment required for successful unpacking.
/// See [`Self::unpack`] method.
fn align() -> usize;
/// Unpack the value from packed value and bytes.
/// `input` must be aligned according to [`Self::align`].
fn unpack<'a>(packed: Self::Packed, input: &'a [u8]) -> Unpacked<'a, Self>;
}
/// Trait for packable types that match specified [`Schema`].
pub trait Pack<T: Schema> {
/// Packs into trivially serializable value.
///
/// Returns packed data and number of bytes used from `output` storage.
fn pack(self, offset: usize, output: &mut [u8]) -> (Packed<T>, usize);
}
/// Type alias for packed value with [`Schema`] of type `T`.
pub type Packed<T> = <T as Schema>::Packed;
/// Type alias for unpacked value with [`Schema`] of type `T`.
pub type Unpacked<'a, T> = <T as SchemaUnpack<'a>>::Unpacked;