use crate::prelude::*;
#[cfg(feature = "encode")]
pub struct EncoderStream<'a, O> {
pub bytes: &'a mut Vec<u8>,
pub lens: &'a mut Vec<usize>,
pub options: &'a O,
}
#[cfg(feature = "encode")]
impl<'a, O: EncodeOptions> EncoderStream<'a, O> {
pub fn new(bytes: &'a mut Vec<u8>, lens: &'a mut Vec<usize>, options: &'a O) -> Self {
Self { bytes, lens, options }
}
pub fn encode_with_id<T: TypeId>(&mut self, f: impl FnOnce(&mut Self) -> T) -> T {
let type_index = self.bytes.len();
self.bytes.push(0);
let id = f(self);
debug_assert!(id != T::void() || (self.bytes.len() == type_index + 1), "Expecting Void to encode no bytes to stream");
self.bytes[type_index] = id.into();
id
}
pub fn encode_with_len<T>(&mut self, f: impl FnOnce(&mut Self) -> T) -> T {
let start = self.bytes.len();
let result = f(self);
self.lens.push(self.bytes.len() - start);
result
}
}
#[cfg(feature = "encode")]
pub trait Encodable: Sized {
type EncoderArray: EncoderArray<Self>;
#[must_use]
fn encode_root<O: EncodeOptions>(&self, stream: &mut EncoderStream<'_, O>) -> RootTypeId;
}
#[cfg(feature = "decode")]
pub trait Decodable: Sized {
type DecoderArray: DecoderArray<Decode = Self>;
fn decode(sticks: DynRootBranch<'_>, options: &impl DecodeOptions) -> DecodeResult<Self>;
}
#[cfg(feature = "encode")]
pub trait EncoderArray<T>: Default {
fn buffer_one<'a, 'b: 'a>(&'a mut self, value: &'b T);
fn buffer_many<'a, 'b: 'a>(&'a mut self, values: &'b [T]) {
profile_method!(buffer_many);
for elem in values {
self.buffer_one(elem);
}
}
fn encode_all<O: EncodeOptions>(values: &[T], stream: &mut EncoderStream<'_, O>) -> ArrayTypeId {
profile_method!(encode_all);
let mut s = Self::default();
s.buffer_many(values);
s.flush(stream)
}
fn flush<O: EncodeOptions>(self, stream: &mut EncoderStream<'_, O>) -> ArrayTypeId;
}
pub trait PrimitiveEncoderArray<T>: EncoderArray<T> {
fn fast_size_for_all<O: EncodeOptions>(_values: &[T], _options: &O) -> usize;
}
#[cfg(feature = "decode")]
pub trait DecoderArray: Sized + Send {
type Error: CoercibleWith<DecodeError> + CoercibleWith<Never>;
type Decode;
fn new(sticks: DynArrayBranch<'_>, options: &impl DecodeOptions) -> DecodeResult<Self>;
fn decode_next(&mut self) -> Result<Self::Decode, Self::Error>;
}
pub trait InfallibleDecoderArray: Sized {
type Decode;
fn new_infallible(sticks: DynArrayBranch<'_>, options: &impl DecodeOptions) -> DecodeResult<Self>;
fn decode_next_infallible(&mut self) -> Self::Decode;
}
impl<T: InfallibleDecoderArray + Send> DecoderArray for T {
type Decode = <Self as InfallibleDecoderArray>::Decode;
type Error = Never;
#[inline(always)]
fn new(sticks: DynArrayBranch<'_>, options: &impl DecodeOptions) -> DecodeResult<Self> {
InfallibleDecoderArray::new_infallible(sticks, options)
}
#[inline(always)]
fn decode_next(&mut self) -> Result<Self::Decode, Self::Error> {
Ok(InfallibleDecoderArray::decode_next_infallible(self))
}
}