1use super::*;
6use crate::varzerovec::lengthless::VarZeroLengthlessSlice;
7use crate::vecs::VarZeroVecFormat;
8use core::{fmt, mem};
9
10)]
19#[repr(transparent)]
20pub struct MultiFieldsULE<const LEN: usize, Format: VarZeroVecFormat>(
21 VarZeroLengthlessSlice<[u8], Format>,
22);
23
24impl<const LEN: usize, Format: VarZeroVecFormat> MultiFieldsULE<LEN, Format> {
25 #[inline]
27 #[expect(clippy::expect_used)] pub fn compute_encoded_len_for(lengths: [usize; LEN]) -> usize {
29 let lengths = lengths.map(BlankSliceEncoder);
30 crate::varzerovec::components::compute_serializable_len_without_length::<_, _, Format>(
31 &lengths,
32 )
33 .expect("Too many bytes to encode") as usize
34 }
35
36 pub fn new_from_lengths_partially_initialized<'a>(
38 lengths: [usize; LEN],
39 output: &'a mut [u8],
40 ) -> &'a mut Self {
41 let lengths = lengths.map(BlankSliceEncoder);
42 crate::varzerovec::components::write_serializable_bytes_without_length::<_, _, Format>(
43 &lengths, output,
44 );
45 if true {
if !<VarZeroLengthlessSlice<[u8],
Format>>::parse_bytes(LEN as u32, output).is_ok() {
{
::core::panicking::panic_fmt(format_args!("Encoded slice must be valid VarZeroSlice"));
}
};
};debug_assert!(
46 <VarZeroLengthlessSlice<[u8], Format>>::parse_bytes(LEN as u32, output).is_ok(),
47 "Encoded slice must be valid VarZeroSlice"
48 );
49 unsafe {
50 let slice = <VarZeroLengthlessSlice<[u8], Format>>::from_bytes_unchecked_mut(output);
52 mem::transmute::<&mut VarZeroLengthlessSlice<[u8], Format>, &mut Self>(slice)
54 }
55 }
56
57 #[inline]
63 pub unsafe fn set_field_at<T: VarULE + ?Sized, A: EncodeAsVarULE<T> + ?Sized>(
64 &mut self,
65 idx: usize,
66 value: &A,
67 ) {
68 value.encode_var_ule_write(self.0.get_bytes_at_mut(LEN as u32, idx))
69 }
70
71 #[inline]
77 pub unsafe fn validate_field<T: VarULE + ?Sized>(&self, index: usize) -> Result<(), UleError> {
78 T::validate_bytes(self.0.get_unchecked(LEN as u32, index))
79 }
80
81 #[inline]
88 pub unsafe fn get_field<T: VarULE + ?Sized>(&self, index: usize) -> &T {
89 T::from_bytes_unchecked(self.0.get_unchecked(LEN as u32, index))
90 }
91
92 #[inline]
97 pub unsafe fn from_bytes_unchecked(bytes: &[u8]) -> &Self {
98 mem::transmute(<VarZeroLengthlessSlice<[u8], Format>>::from_bytes_unchecked(bytes))
100 }
101
102 pub fn as_bytes(&self) -> &[u8] {
104 self.0.as_bytes()
105 }
106}
107
108impl<const LEN: usize, Format: VarZeroVecFormat> fmt::Debug for MultiFieldsULE<LEN, Format> {
109 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
110 f.write_fmt(format_args!("MultiFieldsULE<{1}>({0:?})", self.0.as_bytes(),
LEN))write!(f, "MultiFieldsULE<{LEN}>({:?})", self.0.as_bytes())
111 }
112}
113#[repr(transparent)]
117struct BlankSliceEncoder(usize);
118
119unsafe impl EncodeAsVarULE<[u8]> for BlankSliceEncoder {
120 fn encode_var_ule_as_slices<R>(&self, _: impl FnOnce(&[&[u8]]) -> R) -> R {
121 ::core::panicking::panic("internal error: entered unreachable code")unreachable!()
123 }
124
125 #[inline]
126 fn encode_var_ule_len(&self) -> usize {
127 self.0
128 }
129
130 #[inline]
131 fn encode_var_ule_write(&self, _dst: &mut [u8]) {
132 }
134}
135
136unsafe impl<const LEN: usize, Format: VarZeroVecFormat> VarULE for MultiFieldsULE<LEN, Format> {
145 #[inline]
150 fn validate_bytes(slice: &[u8]) -> Result<(), UleError> {
151 <VarZeroLengthlessSlice<[u8], Format>>::parse_bytes(LEN as u32, slice).map(|_| ())
152 }
153
154 #[inline]
155 unsafe fn from_bytes_unchecked(bytes: &[u8]) -> &Self {
156 mem::transmute(<VarZeroLengthlessSlice<[u8], Format>>::from_bytes_unchecked(bytes))
158 }
159}