use super::*;
use crate::varzerovec::Index32;
use crate::VarZeroSlice;
use core::mem;
#[derive(PartialEq, Eq)]
#[repr(transparent)]
pub struct MultiFieldsULE(VarZeroSlice<[u8], Index32>);
impl MultiFieldsULE {
#[inline]
pub fn compute_encoded_len_for(lengths: &[usize]) -> usize {
#[allow(clippy::expect_used)] unsafe {
let lengths = &*(lengths as *const [usize] as *const [BlankSliceEncoder]);
crate::varzerovec::components::compute_serializable_len::<_, _, Index32>(lengths)
.expect("Too many bytes to encode") as usize
}
}
pub fn new_from_lengths_partially_initialized<'a>(
lengths: &[usize],
output: &'a mut [u8],
) -> &'a mut Self {
unsafe {
let lengths = &*(lengths as *const [usize] as *const [BlankSliceEncoder]);
crate::varzerovec::components::write_serializable_bytes::<_, _, Index32>(
lengths, output,
);
debug_assert!(
<VarZeroSlice<[u8]>>::validate_byte_slice(output).is_ok(),
"Encoded slice must be valid VarZeroSlice"
);
let slice = <VarZeroSlice<[u8], Index32>>::from_byte_slice_unchecked_mut(output);
mem::transmute::<&mut VarZeroSlice<_, Index32>, &mut Self>(slice)
}
}
#[inline]
pub unsafe fn set_field_at<T: VarULE + ?Sized, A: EncodeAsVarULE<T> + ?Sized>(
&mut self,
idx: usize,
value: &A,
) {
value.encode_var_ule_write(self.0.get_bytes_at_mut(idx))
}
#[inline]
pub unsafe fn validate_field<T: VarULE + ?Sized>(
&self,
index: usize,
) -> Result<(), ZeroVecError> {
T::validate_byte_slice(self.0.get_unchecked(index))
}
#[inline]
pub unsafe fn get_field<T: VarULE + ?Sized>(&self, index: usize) -> &T {
T::from_byte_slice_unchecked(self.0.get_unchecked(index))
}
#[inline]
pub unsafe fn from_byte_slice_unchecked(bytes: &[u8]) -> &Self {
mem::transmute(<VarZeroSlice<[u8]>>::from_byte_slice_unchecked(bytes))
}
}
#[repr(transparent)]
struct BlankSliceEncoder(usize);
unsafe impl EncodeAsVarULE<[u8]> for BlankSliceEncoder {
fn encode_var_ule_as_slices<R>(&self, _: impl FnOnce(&[&[u8]]) -> R) -> R {
unreachable!()
}
#[inline]
fn encode_var_ule_len(&self) -> usize {
self.0
}
#[inline]
fn encode_var_ule_write(&self, _dst: &mut [u8]) {
}
}
unsafe impl VarULE for MultiFieldsULE {
#[inline]
fn validate_byte_slice(slice: &[u8]) -> Result<(), ZeroVecError> {
<VarZeroSlice<[u8]>>::validate_byte_slice(slice)
}
#[inline]
unsafe fn from_byte_slice_unchecked(bytes: &[u8]) -> &Self {
mem::transmute(<VarZeroSlice<[u8]>>::from_byte_slice_unchecked(bytes))
}
}