oxidef_compact1 0.1.0-alpha.1

Oxidef is an experimental interface definition language and serialisation scheme for efficient and strongly-typed payloads.
Documentation
use crate::{
    decoder::{DecError, Decoder, MeasureBuf},
    encoder::{EncError, Encoder, ImprovidentBufMut},
};

/// Trait representing an opinion on how to encode and decode `For`.
/// This makes the representation of structs customisable.
pub trait Compact1CodecOpinion<For> {
    fn encode<B: ImprovidentBufMut>(
        &self,
        encoder: &mut Encoder<B>,
        what: &For,
    ) -> Result<(), EncError>
    where
        Self: Sized;

    fn decode<B: MeasureBuf>(&self, decoder: &mut Decoder<B>) -> Result<For, DecError>
    where
        For: Sized;
}

/// Trait representing a type that can be encoded and decoded with no opinion.
///
/// This should only be implemented where the majority of use cases would be covered
/// by the representation and it would not be too surprising to use that encoding.
///
/// In other cases, prefer an explicit [`Compact1CodecOpinion`], which allows customisation
/// of the representation..
///
/// Generally this should favour efficient and dense representations as the default,
/// without favouring some of the value space over others.
/// For example, integers should be represented natively, not using variable-length
/// encoding by default, because this favours smaller values over larger ones.
///
/// The efficiency suggestion also suggests that e.g. bit-packing 53-bit integers
/// would be less favourable than using a 7-byte (56-bit) representation,
/// because byte-alignment is quite important for efficiency.
///
/// All in all: everything is a guideline.
pub trait Compact1Codec {
    fn encode<B: ImprovidentBufMut>(&self, encoder: &mut Encoder<B>) -> Result<(), EncError>
    where
        Self: Sized;

    fn decode<B: MeasureBuf>(decoder: &mut Decoder<B>) -> Result<Self, DecError>
    where
        Self: Sized;
}

/// The empty opinion `()` can represent anything that doesn't need an opinion.
impl<T: Compact1Codec> Compact1CodecOpinion<T> for () {
    fn encode<B: ImprovidentBufMut>(
        &self,
        encoder: &mut Encoder<B>,
        what: &T,
    ) -> Result<(), EncError>
    where
        Self: Sized,
    {
        what.encode(encoder)
    }

    #[inline(always)]
    fn decode<B: MeasureBuf>(&self, decoder: &mut Decoder<B>) -> Result<T, DecError>
    where
        T: Sized,
    {
        <T as Compact1Codec>::decode(decoder)
    }
}