pub(crate) use self::internal::*;
use core::marker::PhantomData;
#[derive(Copy, Clone)]
pub struct Configuration<E = LittleEndian, I = Varint, A = WriteFixedArrayLength, L = NoLimit> {
_e: PhantomData<E>,
_i: PhantomData<I>,
_a: PhantomData<A>,
_l: PhantomData<L>,
}
pub const fn standard() -> Configuration {
generate()
}
pub const fn legacy() -> Configuration<LittleEndian, Fixint, WriteFixedArrayLength, NoLimit> {
generate()
}
impl<E, I, A, L> Default for Configuration<E, I, A, L> {
fn default() -> Self {
generate()
}
}
const fn generate<E, I, A, L>() -> Configuration<E, I, A, L> {
Configuration {
_e: PhantomData,
_i: PhantomData,
_a: PhantomData,
_l: PhantomData,
}
}
impl<E, I, A, L> Configuration<E, I, A, L> {
pub const fn with_big_endian(self) -> Configuration<BigEndian, I, A, L> {
generate()
}
pub const fn with_little_endian(self) -> Configuration<LittleEndian, I, A, L> {
generate()
}
pub const fn with_variable_int_encoding(self) -> Configuration<E, Varint, A, L> {
generate()
}
pub const fn with_fixed_int_encoding(self) -> Configuration<E, Fixint, A, L> {
generate()
}
pub const fn skip_fixed_array_length(self) -> Configuration<E, I, SkipFixedArrayLength, L> {
generate()
}
pub const fn write_fixed_array_length(self) -> Configuration<E, I, WriteFixedArrayLength, L> {
generate()
}
pub const fn with_limit<const N: usize>(self) -> Configuration<E, I, A, Limit<N>> {
generate()
}
pub const fn with_no_limit(self) -> Configuration<E, I, A, NoLimit> {
generate()
}
}
pub trait Config:
InternalEndianConfig
+ InternalArrayLengthConfig
+ InternalIntEncodingConfig
+ InternalLimitConfig
+ Copy
+ Clone
{
}
impl<T> Config for T where
T: InternalEndianConfig
+ InternalArrayLengthConfig
+ InternalIntEncodingConfig
+ InternalLimitConfig
+ Copy
+ Clone
{
}
#[derive(Copy, Clone)]
pub struct BigEndian {}
impl InternalEndianConfig for BigEndian {
const ENDIAN: Endian = Endian::Big;
}
#[derive(Copy, Clone)]
pub struct LittleEndian {}
impl InternalEndianConfig for LittleEndian {
const ENDIAN: Endian = Endian::Little;
}
#[derive(Copy, Clone)]
pub struct Fixint {}
impl InternalIntEncodingConfig for Fixint {
const INT_ENCODING: IntEncoding = IntEncoding::Fixed;
}
#[derive(Copy, Clone)]
pub struct Varint {}
impl InternalIntEncodingConfig for Varint {
const INT_ENCODING: IntEncoding = IntEncoding::Variable;
}
#[derive(Copy, Clone)]
pub struct SkipFixedArrayLength {}
impl InternalArrayLengthConfig for SkipFixedArrayLength {
const SKIP_FIXED_ARRAY_LENGTH: bool = true;
}
#[derive(Copy, Clone)]
pub struct WriteFixedArrayLength {}
impl InternalArrayLengthConfig for WriteFixedArrayLength {
const SKIP_FIXED_ARRAY_LENGTH: bool = false;
}
#[derive(Copy, Clone)]
pub struct NoLimit {}
impl InternalLimitConfig for NoLimit {
const LIMIT: Option<usize> = None;
}
#[derive(Copy, Clone)]
pub struct Limit<const N: usize> {}
impl<const N: usize> InternalLimitConfig for Limit<N> {
const LIMIT: Option<usize> = Some(N);
}
mod internal {
use super::Configuration;
pub trait InternalEndianConfig {
const ENDIAN: Endian;
}
impl<E: InternalEndianConfig, I, A, L> InternalEndianConfig for Configuration<E, I, A, L> {
const ENDIAN: Endian = E::ENDIAN;
}
#[derive(PartialEq, Eq)]
pub enum Endian {
Little,
Big,
}
pub trait InternalIntEncodingConfig {
const INT_ENCODING: IntEncoding;
}
impl<E, I: InternalIntEncodingConfig, A, L> InternalIntEncodingConfig
for Configuration<E, I, A, L>
{
const INT_ENCODING: IntEncoding = I::INT_ENCODING;
}
#[derive(PartialEq, Eq)]
pub enum IntEncoding {
Fixed,
Variable,
}
pub trait InternalArrayLengthConfig {
const SKIP_FIXED_ARRAY_LENGTH: bool;
}
impl<E, I, A: InternalArrayLengthConfig, L> InternalArrayLengthConfig
for Configuration<E, I, A, L>
{
const SKIP_FIXED_ARRAY_LENGTH: bool = A::SKIP_FIXED_ARRAY_LENGTH;
}
pub trait InternalLimitConfig {
const LIMIT: Option<usize>;
}
impl<E, I, A, L: InternalLimitConfig> InternalLimitConfig for Configuration<E, I, A, L> {
const LIMIT: Option<usize> = L::LIMIT;
}
}