usesuper::*; usecrate::varzerovec::lengthless::VarZeroLengthlessSlice; usecrate::vecs::VarZeroVecFormat; use core::{fmt, mem};
/// This type is used by the custom derive to represent multiple [`VarULE`] /// fields packed into a single end-of-struct field. It is not recommended /// to use this type directly, use [`Tuple2VarULE`](crate::ule::tuplevar::Tuple2VarULE) etc instead. /// /// Logically, consider it to be `(, , , ..)` /// where `` etc are potentially different [`VarULE`] types. /// /// Internally, it is represented by a VarZeroSlice without the length part. #[derive(PartialEq, Eq)] #[repr(transparent)] pubstruct MultiFieldsULE<const LEN: usize, Format: VarZeroVecFormat>(
VarZeroLengthlessSlice<[u8], Format>,
);
impl<const LEN: usize, Format: VarZeroVecFormat> MultiFieldsULE<LEN, Format> { /// Compute the amount of bytes needed to support elements with lengths `lengths` #[inline] #[expect(clippy::expect_used)] // See #1410 pubfn compute_encoded_len_for(lengths: [usize; LEN]) -> usize { let lengths = lengths.map(BlankSliceEncoder); crate::varzerovec::components::compute_serializable_len_without_length::<_, _, Format>(
&lengths,
)
.expect("Too many bytes to encode") as usize
}
/// Construct a partially initialized MultiFieldsULE backed by a mutable byte buffer pubfn new_from_lengths_partially_initialized<'a>(
lengths: [usize; LEN],
output: &'a mut [u8],
) -> &'a mut Self { let lengths = lengths.map(BlankSliceEncoder); crate::varzerovec::components::write_serializable_bytes_without_length::<_, _, Format>(
&lengths, output,
);
debug_assert!(
<VarZeroLengthlessSlice<[u8], Format>>::parse_bytes(LEN as u32, output).is_ok(), "Encoded slice must be valid VarZeroSlice"
); unsafe { // Safe since write_serializable_bytes produces a valid VarZeroLengthlessSlice buffer with the right format let slice = <VarZeroLengthlessSlice<[u8], Format>>::from_bytes_unchecked_mut(output); // safe since `Self` is transparent over VarZeroLengthlessSlice<[u8], Format>
mem::transmute::<&mut VarZeroLengthlessSlice<[u8], Format>, & style='color:red'>mutSelf>(slice)
}
}
/// Given a buffer of size obtained by [`Self::compute_encoded_len_for()`], write element A to index idx /// /// # Safety /// - `idx` must be in range /// - `T` must be the appropriate type expected by the custom derive in this usage of this type #[inline] pubunsafefn set_field_at<T: VarULE + ?Sized, A: EncodeAsVarULE<T> + ?Sized>(
&mutself,
idx: usize,
value: &A,
) {
value.encode_var_ule_write(self.0.get_bytes_at_mut(LEN as u32, idx))
}
/// Validate field at `index` to see if it is a valid `T` VarULE type /// /// # Safety /// /// - `index` must be in range #[inline] pubunsafefn validate_field<T: VarULE + ?Sized>(&self, index: usize) -> Result<(), UleError> {
T::validate_bytes(self.0.get_unchecked(LEN as u32, index))
}
/// Get field at `index` as a value of type T /// /// # Safety /// /// - `index` must be in range /// - Element at `index` must have been created with the VarULE type T #[inline] pubunsafefn get_field<T: VarULE + ?Sized>(&self, index: usize) -> &T {
T::from_bytes_unchecked(self.0.get_unchecked(LEN as u32, index))
}
/// Construct from a byte slice /// /// # Safety /// - byte slice must be a valid VarZeroLengthlessSlice<[u8], Format> with length LEN #[inline] pubunsafefn from_bytes_unchecked(bytes: &[u8]) -> &Self { // &Self is transparent over &VZS<..> with the right format
mem::transmute(<VarZeroLengthlessSlice<[u8], Format>>::from_bytes_unchecked(bytes))
}
/// Get the bytes behind this value pubfn as_bytes(&self) -> &[u8] { self.0.as_bytes()
}
}
impl<const LEN: usize, Format: VarZeroVecFormat> fmt::Debug for MultiFieldsULE<LEN, Format> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "MultiFieldsULE<{LEN}>({:?})", self.0.as_bytes())
}
} /// This lets us conveniently use the EncodeAsVarULE functionality to create /// `VarZeroVec<[u8]>`s that have the right amount of space for elements /// without having to duplicate any unsafe code #[repr(transparent)] struct BlankSliceEncoder(usize);
unsafeimpl EncodeAsVarULE<[u8]> for BlankSliceEncoder { fn encode_var_ule_as_slices<R>(&self, _: impl FnOnce(&[&[u8]]) -> R) -> R { // unnecessary if the other two are implemented
unreachable!()
}
// Safety (based on the safety checklist on the VarULE trait): // 1. MultiFieldsULE does not include any uninitialized or padding bytes (achieved by being transparent over a VarULE type) // 2. MultiFieldsULE is aligned to 1 byte (achieved by being transparent over a VarULE type) // 3. The impl of `validate_bytes()` returns an error if any byte is not valid. // 4. The impl of `validate_bytes()` returns an error if the slice cannot be used in its entirety // 5. The impl of `from_bytes_unchecked()` returns a reference to the same data. // 6. All other methods are defaulted // 7. `MultiFieldsULE` byte equality is semantic equality (achieved by being transparent over a VarULE type) unsafeimpl<const LEN: usize, Format: VarZeroVecFormat> VarULE for MultiFieldsULE<LEN, Format> { /// Note: MultiFieldsULE is usually used in cases where one should be calling .validate_field() directly for /// each field, rather than using the regular VarULE impl. /// /// This impl exists so that EncodeAsVarULE can work. #[inline] fn validate_bytes(slice: &[u8]) -> Result<(), UleError> {
<VarZeroLengthlessSlice<[u8], Format>>::parse_bytes(LEN as u32, slice).map(|_| ())
}
#[inline] unsafefn from_bytes_unchecked(bytes: &[u8]) -> &Self { // &Self is transparent over &VZS<..>
mem::transmute(<VarZeroLengthlessSlice<[u8], Format>>::from_bytes_unchecked(bytes))
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.27 Sekunden
(vorverarbeitet am 2026-08-27)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.