Skip to main content

ab_io_type/
trivial_type.rs

1use crate::IoType;
2use crate::alignment::Alignment;
3use crate::metadata::{IoTypeMetadataKind, MAX_METADATA_CAPACITY, concat_metadata_sources};
4use crate::unaligned::Unaligned;
5pub use ab_io_type_derive::TrivialType;
6use core::ops::{Deref, DerefMut};
7use core::ptr::NonNull;
8use core::{ptr, slice};
9
10const SIZE_OF<T>: usize = size_of::<T>();
11/// Ensures the number of array elements (encoded in metadata) and array size fit into `u32`
12const SUPPORTED_ARRAY<T, const N: usize>: usize = {
13    assert!(
14        u32::MAX as usize >= N,
15        "Number of array elements must be smaller than 2^32"
16    );
17    assert!(
18        u32::MAX as usize >= size_of::<[T; N]>(),
19        "Type size must be smaller than 2^32"
20    );
21    0
22};
23/// Ensures `T` is not zero-sized, which some containers can't represent
24pub(crate) const NON_ZERO_SIZED<T: TrivialType>: usize = {
25    assert!(T::SIZE > 0, "Zero-sized types are not supported");
26    0
27};
28
29// TODO: Make this a `const` trait, with `const` impls generated by the derive, once const traits
30//  are stable, deriving crates would need `#![feature(const_trait_impl)]` otherwise:
31//  https://github.com/rust-lang/rust/issues/143874
32/// Simple wrapper data type that is designed in such a way that its serialization/deserialization
33/// is the same as the type itself.
34///
35/// Serialization takes the bytes of a value. Deserialization parses bytes: the parsing step checks
36/// that they are a valid value of the type, which is a length check for types that accept every
37/// bit pattern (see [`AnyBitPattern`]). Bytes that are not aligned for the type are parsed with the
38/// methods of [`Unaligned`], like `Unaligned::<T>::try_from_bytes()`.
39///
40/// A valid value is one whose every field is a valid value of its type, like `0` or `1` for a
41/// `bool` and the index of a variant for the discriminant of an enum, and that satisfies the
42/// invariants `unsafe` code relies on. Parsing may reject more, like a length of
43/// `FixedCapacityElements` above its capacity, but doesn't check encoding rules, like the bytes of
44/// its length prefix after the length.
45///
46/// # Safety
47/// * There is no padding, every byte is initialized and there is no interior mutability
48/// * The alignment is at most [`Alignment::MAX`]
49/// * [`Self::SIZE`] is not overridden
50/// * [`Self::ALIGNMENT`] is the alignment that [`Self::METADATA`] decodes to, and it is at least
51///   `align_of::<Self>()`
52/// * The parsing step `parse_step::<ALIGNED>()` returns `Some((value, remainder))` only if `bytes`
53///   start with `size_of::<Self>()` bytes that are a valid value of `Self`, `value` points to the
54///   beginning of `bytes` and `remainder` is the rest of `bytes` after those bytes. This holds for
55///   both flavours: the aligned one (`ALIGNED` is `true`) gets `bytes` aligned for `Self`, the
56///   unaligned one gets `bytes` of any alignment
57///
58/// Implementations are expected to be composites of existing `TrivialType`s without custom
59/// alignment, whose alignment is then at most [`Alignment::MAX`] as well. Prefer
60/// `#[derive(TrivialType)]`, which upholds this contract.
61///
62/// # Deriving
63/// `#[derive(TrivialType)]` supports structs and enums and checks the following requirements at
64/// compile time:
65/// * no generic parameters, and types of all fields implement `TrivialType`
66/// * structs are `#[repr(C)]` or `#[repr(transparent)]` without other options
67/// * enums are `#[repr(u8)]` without other options
68/// * no `#[repr(align(N))]` or `#[repr(packed)]` in any `#[repr(..)]` attribute, [`Unaligned`] can
69///   be used to reduce the alignment of a field to one byte instead
70/// * no implicit padding, explicit `padding: [u8; N]` fields can be added where necessary. Padding
71///   is determined by [`TrivialType::ALIGNMENT`] of the field types. Each variant of an enum is
72///   laid out like a `#[repr(C)]` struct with the discriminant as the first field, so fields of all
73///   variants must have the same total size
74/// * explicit discriminants of enum variants are equal to the index of the variant, metadata
75///   identifies variants by their index and doesn't record discriminants
76/// * at most 255 fields in a struct or enum variant and at most 255 variants in an enum, names of
77///   the type, its fields and variants are at most 255 bytes long
78/// * size is smaller than 2^32 bytes
79/// * metadata, including metadata of field types, is at most [`MAX_METADATA_CAPACITY`] bytes,
80///   otherwise const evaluation panics with an opaque error
81/// * structs parse their fields in order, enums check the discriminant and parse the fields of that
82///   variant
83/// * deriving means that any combination of valid field values is a valid value of the type,
84///   private fields and `#[non_exhaustive]` included, because parsing creates values without
85///   calling constructors, unless `#[trivial_type(validate = path)]` rejects it
86/// * structs implement [`AnyBitPatternMarker`] when all their fields do, unless they use
87///   `#[trivial_type(validate = path)]`
88///
89/// Invariants that `unsafe` code relies on are checked with `#[trivial_type(validate = path)]`.
90/// `path` is called as `path(value: &Self) -> bool` after all fields were parsed and must return
91/// `false` for every value that `unsafe` code relying on the invariants can't handle. It must not
92/// panic, since parsing is used in code that is verified not to panic, and a `const fn` is
93/// recommended, the derive may become `const` later. Such types don't implement
94/// [`AnyBitPatternMarker`].
95///
96/// It is called by every parsing method, including those of arrays of the type, of [`Unaligned`]
97/// and of containers through [`IoType::try_from_ptr()`] and [`IoType::try_from_mut_ptr()`]. The
98/// unsafe methods that skip parsing, [`IoType::from_ptr()`], [`IoType::from_mut_ptr()`] and derives
99/// of other crates, like SCALE's `Decode` and serde's `Deserialize`, don't call it.
100pub unsafe trait TrivialType
101where
102    Self: Copy + 'static,
103{
104    // TODO: Make it `final` once supported:
105    //  https://internals.rust-lang.org/t/final-associated-constants/24655
106    const SIZE: u32 = {
107        assert!(
108            u32::MAX as usize >= size_of::<Self>(),
109            "Type size must be smaller than 2^32"
110        );
111        size_of::<Self>() as u32
112    };
113    /// Alignment of the type in metadata.
114    ///
115    /// Integers and `bool` are aligned to their size, `()` and [`Unaligned`] to 1 byte, other types
116    /// to the largest alignment of their contents. It is never smaller than `align_of::<Self>()`,
117    /// so memory aligned to it is aligned for `Self`.
118    const ALIGNMENT: Alignment;
119    /// Data structure metadata in binary form, describing shape and types of the contents, see
120    /// [`IoTypeMetadataKind`] for encoding details.
121    const METADATA: &[u8];
122
123    /// Parse the beginning of `bytes`, which are aligned for `Self` if `ALIGNED`.
124    ///
125    /// Returns the value and the remaining bytes, or `None` if `bytes` are shorter than the type or
126    /// don't start with a valid value. `#[derive(TrivialType)]` implements it, the other parsing
127    /// methods are built on it. Values in memory that is not aligned for `Self` are read with the
128    /// methods of [`Unaligned<Self>`], like `Unaligned::<Self>::try_from_bytes()`.
129    ///
130    /// Both flavours must accept the same values. The aligned one can use aligned loads, which
131    /// matters on targets without fast unaligned access, where unaligned loads wider than a byte
132    /// compile to several byte loads.
133    ///
134    /// # Safety
135    /// If `ALIGNED`, `bytes` are aligned for `Self`.
136    #[doc(hidden)]
137    unsafe fn parse_step<const ALIGNED: bool>(bytes: &[u8]) -> Option<(&Unaligned<Self>, &[u8])>;
138
139    /// Parse the beginning of aligned `bytes`, returns the value and the remaining bytes.
140    ///
141    /// Returns `None` if `bytes` are not aligned for `Self`, are too short or don't start with a
142    /// valid value.
143    #[inline(always)]
144    final fn try_from_bytes(bytes: &[u8]) -> Option<(&Self, &[u8])> {
145        if !bytes.as_ptr().cast::<Self>().is_aligned() {
146            return None;
147        }
148        // SAFETY: Aligned as checked above
149        let (_value, remainder) = unsafe { Self::parse_step::<true>(bytes) }?;
150        // SAFETY: `bytes` start with a valid value of `Self` (parsing step contract), aligned as
151        // checked above
152        let value = unsafe { bytes.as_ptr().cast::<Self>().as_ref_unchecked() };
153        Some((value, remainder))
154    }
155
156    /// Like [`Self::try_from_bytes()`], but returns `None` if there are more bytes than the value
157    #[inline(always)]
158    final fn try_from_bytes_exact(bytes: &[u8]) -> Option<&Self> {
159        let (value, remainder) = Self::try_from_bytes(bytes)?;
160        remainder.is_empty().then_some(value)
161    }
162
163    /// Like [`Self::try_from_bytes()`], but returns an exclusive reference.
164    ///
165    /// Only valid values of `Self` can be written through it, so the bytes stay a valid value.
166    #[inline(always)]
167    final fn try_from_bytes_mut(bytes: &mut [u8]) -> Option<(&mut Self, &mut [u8])> {
168        if !bytes.as_ptr().cast::<Self>().is_aligned() {
169            return None;
170        }
171        // SAFETY: Aligned as checked above
172        unsafe { Self::parse_step::<true>(bytes) }?;
173        let (value, remainder) = bytes.split_at_mut_checked(size_of::<Self>())?;
174        // SAFETY: `bytes` start with a valid value of `Self` (parsing step contract), aligned as
175        // checked above, only valid values of `Self` can be written through the reference, and
176        // they have no padding, so the bytes stay initialized. It is derived from `bytes`, not
177        // from the shared reference the parsing step returned.
178        let value = unsafe { value.as_mut_ptr().cast::<Self>().as_mut_unchecked() };
179        Some((value, remainder))
180    }
181
182    /// Like [`Self::try_from_bytes_mut()`], but returns `None` if there are more bytes than the
183    /// value
184    #[inline(always)]
185    final fn try_from_bytes_mut_exact(bytes: &mut [u8]) -> Option<&mut Self> {
186        let (value, remainder) = Self::try_from_bytes_mut(bytes)?;
187        remainder.is_empty().then_some(value)
188    }
189
190    /// Create a reference to a value at the beginning of aligned `bytes`, returns the value and
191    /// the remaining bytes.
192    ///
193    /// Returns `None` if `bytes` are not aligned for `Self` or are too short. Unlike
194    /// [`Self::try_from_bytes()`] it doesn't parse the bytes, since any bytes are a valid value.
195    #[inline(always)]
196    final fn from_bytes(bytes: &[u8]) -> Option<(&Self, &[u8])>
197    where
198        Self: AnyBitPattern,
199    {
200        if !bytes.as_ptr().cast::<Self>().is_aligned() {
201            return None;
202        }
203        let (value, remainder) = bytes.split_at_checked(size_of::<Self>())?;
204        // SAFETY: `value` is `size_of::<Self>()` initialized bytes, aligned as checked above, and
205        // any of them are a valid value of `Self` (`AnyBitPatternMarker`)
206        let value = unsafe { value.as_ptr().cast::<Self>().as_ref_unchecked() };
207        Some((value, remainder))
208    }
209
210    /// Like [`Self::from_bytes()`], but returns `None` if there are more bytes than the value
211    #[inline(always)]
212    final fn from_bytes_exact(bytes: &[u8]) -> Option<&Self>
213    where
214        Self: AnyBitPattern,
215    {
216        let (value, remainder) = Self::from_bytes(bytes)?;
217        remainder.is_empty().then_some(value)
218    }
219
220    /// Similar to [`Self::from_bytes()`], but for any type and without any checks
221    ///
222    /// # Safety
223    /// `bytes` are aligned for `Self` and start with a valid value of `Self`.
224    #[inline(always)]
225    final unsafe fn from_bytes_unchecked(bytes: &[u8]) -> &Self {
226        // SAFETY: Guaranteed by function contract
227        unsafe { bytes.as_ptr().cast::<Self>().as_ref_unchecked() }
228    }
229
230    /// Like [`Self::from_bytes()`], but returns an exclusive reference
231    #[inline(always)]
232    final fn from_bytes_mut(bytes: &mut [u8]) -> Option<(&mut Self, &mut [u8])>
233    where
234        Self: AnyBitPattern,
235    {
236        if !bytes.as_ptr().cast::<Self>().is_aligned() {
237            return None;
238        }
239        let (value, remainder) = bytes.split_at_mut_checked(size_of::<Self>())?;
240        // SAFETY: `value` is `size_of::<Self>()` initialized bytes, aligned as checked above, and
241        // any of them are a valid value of `Self` (`AnyBitPatternMarker`), values written through
242        // the reference have no padding, so the bytes stay initialized
243        let value = unsafe { value.as_mut_ptr().cast::<Self>().as_mut_unchecked() };
244        Some((value, remainder))
245    }
246
247    /// Like [`Self::from_bytes_mut()`], but returns `None` if there are more bytes than the value
248    #[inline(always)]
249    final fn from_bytes_mut_exact(bytes: &mut [u8]) -> Option<&mut Self>
250    where
251        Self: AnyBitPattern,
252    {
253        let (value, remainder) = Self::from_bytes_mut(bytes)?;
254        remainder.is_empty().then_some(value)
255    }
256
257    /// Similar to [`Self::from_bytes_mut()`], but for any type and without any checks
258    ///
259    /// # Safety
260    /// `bytes` are aligned for `Self` and start with a valid value of `Self`.
261    #[inline(always)]
262    final unsafe fn from_bytes_mut_unchecked(bytes: &mut [u8]) -> &mut Self {
263        // SAFETY: Guaranteed by function contract
264        unsafe { bytes.as_mut_ptr().cast::<Self>().as_mut_unchecked() }
265    }
266
267    /// Create a slice of `count` values at the beginning of aligned `bytes`, returns the values and
268    /// the remaining bytes.
269    ///
270    /// Returns `None` if `bytes` are not aligned for `Self` or are too short. Like
271    /// [`Self::from_bytes()`] it doesn't parse the bytes, since any bytes are a valid value.
272    #[inline(always)]
273    final fn slice_from_bytes(bytes: &[u8], count: usize) -> Option<(&[Self], &[u8])>
274    where
275        Self: AnyBitPattern,
276    {
277        if !bytes.as_ptr().cast::<Self>().is_aligned() {
278            return None;
279        }
280        let (values, remainder) = bytes.split_at_checked(count.checked_mul(size_of::<Self>())?)?;
281        // SAFETY: `values` are `count` times `size_of::<Self>()` initialized bytes, aligned as
282        // checked above, and any of them are valid values of `Self` (`AnyBitPatternMarker`)
283        let values = unsafe { slice::from_raw_parts(values.as_ptr().cast::<Self>(), count) };
284        Some((values, remainder))
285    }
286
287    /// Like [`Self::slice_from_bytes()`], but returns an exclusive reference
288    #[inline(always)]
289    final fn slice_from_bytes_mut(
290        bytes: &mut [u8],
291        count: usize,
292    ) -> Option<(&mut [Self], &mut [u8])>
293    where
294        Self: AnyBitPattern,
295    {
296        if !bytes.as_ptr().cast::<Self>().is_aligned() {
297            return None;
298        }
299        let (values, remainder) =
300            bytes.split_at_mut_checked(count.checked_mul(size_of::<Self>())?)?;
301        // SAFETY: `values` are `count` times `size_of::<Self>()` initialized bytes, aligned as
302        // checked above, and any of them are valid values of `Self` (`AnyBitPatternMarker`),
303        // values written through the reference have no padding, so the bytes stay initialized
304        let values =
305            unsafe { slice::from_raw_parts_mut(values.as_mut_ptr().cast::<Self>(), count) };
306        Some((values, remainder))
307    }
308
309    /// Access the underlying byte representation of a data structure
310    #[inline(always)]
311    final fn as_bytes(&self) -> &[u8; SIZE_OF::<Self>] {
312        // SAFETY: All bits are valid for reading as bytes, see `TrivialType` description
313        unsafe { ptr::from_ref(self).cast::<[u8; _]>().as_ref_unchecked() }
314    }
315
316    /// Access the underlying byte representation of a slice of values
317    #[inline(always)]
318    final fn slice_as_bytes(values: &[Self]) -> &[u8] {
319        // SAFETY: All bits are valid for reading as bytes, see `TrivialType` description
320        unsafe { slice::from_raw_parts(values.as_ptr().cast::<u8>(), size_of_val(values)) }
321    }
322
323    /// Access the underlying mutable byte representation of a data structure
324    #[inline(always)]
325    final fn as_bytes_mut(&mut self) -> &mut [u8; SIZE_OF::<Self>]
326    where
327        Self: AnyBitPattern,
328    {
329        // SAFETY: Any bytes written are a valid value of `Self` (`AnyBitPatternMarker`)
330        unsafe { self.as_bytes_mut_unchecked() }
331    }
332
333    /// Similar to [`Self::as_bytes_mut()`], but for any type.
334    ///
335    /// # Safety
336    /// Only bytes of a valid value of `Self` may be written to the returned array.
337    #[inline(always)]
338    final unsafe fn as_bytes_mut_unchecked(&mut self) -> &mut [u8; SIZE_OF::<Self>] {
339        // SAFETY: All bits are valid for reading as bytes, see `TrivialType` description, only
340        // bytes of a valid value are written (function contract)
341        unsafe { ptr::from_mut(self).cast::<[u8; _]>().as_mut_unchecked() }
342    }
343}
344
345// TODO: This trait only exists because `try_as_dyn()`, the only way to detect it in generic code,
346//  skips impls whose bounds mention a type parameter inside a constant, like the array size limit
347//  of `TrivialType for [T; N]`. Merge it into `AnyBitPattern` once that is fixed:
348//  https://github.com/rust-lang/rust/issues/164149
349/// Every bit pattern of the type is a valid value.
350///
351/// Together with [`TrivialType`] it provides [`AnyBitPattern`], which is the bound to use.
352/// `#[derive(TrivialType)]` implements it for structs whose fields all implement it, unless they
353/// use `#[trivial_type(validate = path)]`.
354///
355/// # Safety
356/// Every pattern of `size_of::<Self>()` initialized bytes is a valid value of `Self` that no
357/// invariant of `Self` excludes, not even one that only safe code relies on (like a length that
358/// must not exceed a capacity, or one that `#[trivial_type(validate = path)]` checks), so bytes of
359/// `Self` never need to be checked. If `Self` implements [`TrivialType`], both flavours of its
360/// parsing step `parse_step::<ALIGNED>()` accept every such pattern.
361#[diagnostic::on_unimplemented(message = "`{Self}` doesn't accept every bit pattern")]
362pub unsafe trait AnyBitPatternMarker {}
363
364/// [`TrivialType`] whose every bit pattern is a valid value.
365///
366/// Implemented for every type that implements [`TrivialType`] and [`AnyBitPatternMarker`].
367#[diagnostic::on_unimplemented(message = "`{Self}` doesn't accept every bit pattern")]
368pub trait AnyBitPattern
369where
370    Self: TrivialType + AnyBitPatternMarker,
371{
372}
373
374// Without this attribute errors report the unsatisfied `AnyBitPatternMarker` bound instead,
375// suggesting to require the marker or to implement the `unsafe` marker manually
376#[diagnostic::do_not_recommend]
377impl<T> AnyBitPattern for T where T: TrivialType + AnyBitPatternMarker {}
378
379/// Parsing step of a type whose every bit pattern is a valid value
380#[inline(always)]
381fn try_from_bytes_any_bit_pattern<T>(bytes: &[u8]) -> Option<(&Unaligned<T>, &[u8])>
382where
383    T: TrivialType + AnyBitPatternMarker,
384{
385    let (bytes, remainder) = bytes.split_at_checked(size_of::<T>())?;
386    // SAFETY: `Unaligned<T>` has alignment 1 and the size of `T`, `bytes` are that many
387    // initialized bytes, and any of them are a valid value of `T` (`AnyBitPatternMarker`)
388    let value = unsafe { bytes.as_ptr().cast::<Unaligned<T>>().as_ref_unchecked() };
389    Some((value, remainder))
390}
391
392/// Returns the bytes after `count` valid values of `T` at the beginning of `bytes`.
393///
394/// # Safety
395/// If `ALIGNED`, `bytes` are aligned for `T`.
396#[inline(always)]
397pub(crate) unsafe fn try_skip_valid<T, const ALIGNED: bool>(
398    bytes: &[u8],
399    count: usize,
400) -> Option<&[u8]>
401where
402    T: TrivialType,
403{
404    // Zero-sized values have no bytes, so only a check like a `validate` hook can reject one, and
405    // it rejects either all of them or none, so one check replaces `count` steps that don't consume
406    // bytes
407    if size_of::<T>() == 0 {
408        if count > 0 {
409            // SAFETY: If `ALIGNED`, `bytes` are aligned for `T` (function contract)
410            unsafe { T::parse_step::<ALIGNED>(bytes) }?;
411        }
412        return Some(bytes);
413    }
414    // With all elements split off first, every step gets exactly the bytes of one element, so for
415    // types whose step only checks the length the loop is optimized away
416    let (elements, remainder) = bytes.split_at_checked(count.checked_mul(size_of::<T>())?)?;
417    for element in elements.as_chunks::<{ SIZE_OF::<T> }>().0 {
418        // SAFETY: If `ALIGNED`, `bytes` are aligned for `T` (function contract), and each element
419        // is at an offset into them that is a multiple of the size of `T`, and so of its alignment
420        unsafe { T::parse_step::<ALIGNED>(element) }?;
421    }
422    Some(remainder)
423}
424
425// SAFETY: Any bit pattern is valid, so it is safe to implement `TrivialType` for this type
426unsafe impl TrivialType for () {
427    const ALIGNMENT: Alignment = Alignment::from_power(0)
428        .expect("Alignment of a primitive type is larger than `Alignment::MAX`");
429    const METADATA: &[u8] = &[IoTypeMetadataKind::Unit as u8];
430
431    #[inline(always)]
432    unsafe fn parse_step<const ALIGNED: bool>(bytes: &[u8]) -> Option<(&Unaligned<Self>, &[u8])> {
433        try_from_bytes_any_bit_pattern(bytes)
434    }
435}
436// SAFETY: Zero-sized, its only value has no bytes, the parsing step only checks the length
437unsafe impl AnyBitPatternMarker for () {}
438// SAFETY: One byte, the parsing step accepts only `0` and `1`, the valid values of `bool`
439unsafe impl TrivialType for bool {
440    const ALIGNMENT: Alignment = Alignment::from_power(0)
441        .expect("Alignment of a primitive type is larger than `Alignment::MAX`");
442    const METADATA: &[u8] = &[IoTypeMetadataKind::Bool as u8];
443
444    #[inline(always)]
445    unsafe fn parse_step<const ALIGNED: bool>(bytes: &[u8]) -> Option<(&Unaligned<Self>, &[u8])> {
446        let (&[0 | 1], remainder) = bytes.split_first_chunk::<1>()? else {
447            return None;
448        };
449        // SAFETY: `Unaligned<bool>` is one byte with alignment 1, the first byte is `0` or `1`
450        let value = unsafe { bytes.as_ptr().cast::<Unaligned<Self>>().as_ref_unchecked() };
451        Some((value, remainder))
452    }
453}
454// SAFETY: Any bit pattern is valid, so it is safe to implement `TrivialType` for this type
455unsafe impl TrivialType for u8 {
456    const ALIGNMENT: Alignment = Alignment::from_power(0)
457        .expect("Alignment of a primitive type is larger than `Alignment::MAX`");
458    const METADATA: &[u8] = &[IoTypeMetadataKind::U8 as u8];
459
460    #[inline(always)]
461    unsafe fn parse_step<const ALIGNED: bool>(bytes: &[u8]) -> Option<(&Unaligned<Self>, &[u8])> {
462        try_from_bytes_any_bit_pattern(bytes)
463    }
464}
465// SAFETY: Any bit pattern is a valid value of integers, the parsing step only checks the length
466unsafe impl AnyBitPatternMarker for u8 {}
467// SAFETY: Any bit pattern is valid, so it is safe to implement `TrivialType` for this type
468unsafe impl TrivialType for u16 {
469    const ALIGNMENT: Alignment = Alignment::from_power(1)
470        .expect("Alignment of a primitive type is larger than `Alignment::MAX`");
471    const METADATA: &[u8] = &[IoTypeMetadataKind::U16 as u8];
472
473    #[inline(always)]
474    unsafe fn parse_step<const ALIGNED: bool>(bytes: &[u8]) -> Option<(&Unaligned<Self>, &[u8])> {
475        try_from_bytes_any_bit_pattern(bytes)
476    }
477}
478// SAFETY: Any bit pattern is a valid value of integers, the parsing step only checks the length
479unsafe impl AnyBitPatternMarker for u16 {}
480// SAFETY: Any bit pattern is valid, so it is safe to implement `TrivialType` for this type
481unsafe impl TrivialType for u32 {
482    const ALIGNMENT: Alignment = Alignment::from_power(2)
483        .expect("Alignment of a primitive type is larger than `Alignment::MAX`");
484    const METADATA: &[u8] = &[IoTypeMetadataKind::U32 as u8];
485
486    #[inline(always)]
487    unsafe fn parse_step<const ALIGNED: bool>(bytes: &[u8]) -> Option<(&Unaligned<Self>, &[u8])> {
488        try_from_bytes_any_bit_pattern(bytes)
489    }
490}
491// SAFETY: Any bit pattern is a valid value of integers, the parsing step only checks the length
492unsafe impl AnyBitPatternMarker for u32 {}
493// SAFETY: Any bit pattern is valid, so it is safe to implement `TrivialType` for this type
494unsafe impl TrivialType for u64 {
495    const ALIGNMENT: Alignment = Alignment::from_power(3)
496        .expect("Alignment of a primitive type is larger than `Alignment::MAX`");
497    const METADATA: &[u8] = &[IoTypeMetadataKind::U64 as u8];
498
499    #[inline(always)]
500    unsafe fn parse_step<const ALIGNED: bool>(bytes: &[u8]) -> Option<(&Unaligned<Self>, &[u8])> {
501        try_from_bytes_any_bit_pattern(bytes)
502    }
503}
504// SAFETY: Any bit pattern is a valid value of integers, the parsing step only checks the length
505unsafe impl AnyBitPatternMarker for u64 {}
506// SAFETY: Any bit pattern is valid, so it is safe to implement `TrivialType` for this type
507unsafe impl TrivialType for u128 {
508    // `Alignment::MAX` because native alignment for `u128` is 8 bytes (instead of 16) on 32-bit
509    // platforms
510    const ALIGNMENT: Alignment = Alignment::MAX;
511    const METADATA: &[u8] = &[IoTypeMetadataKind::U128 as u8];
512
513    #[inline(always)]
514    unsafe fn parse_step<const ALIGNED: bool>(bytes: &[u8]) -> Option<(&Unaligned<Self>, &[u8])> {
515        try_from_bytes_any_bit_pattern(bytes)
516    }
517}
518// SAFETY: Any bit pattern is a valid value of integers, the parsing step only checks the length
519unsafe impl AnyBitPatternMarker for u128 {}
520// SAFETY: Any bit pattern is valid, so it is safe to implement `TrivialType` for this type
521unsafe impl TrivialType for i8 {
522    const ALIGNMENT: Alignment = Alignment::from_power(0)
523        .expect("Alignment of a primitive type is larger than `Alignment::MAX`");
524    const METADATA: &[u8] = &[IoTypeMetadataKind::I8 as u8];
525
526    #[inline(always)]
527    unsafe fn parse_step<const ALIGNED: bool>(bytes: &[u8]) -> Option<(&Unaligned<Self>, &[u8])> {
528        try_from_bytes_any_bit_pattern(bytes)
529    }
530}
531// SAFETY: Any bit pattern is a valid value of integers, the parsing step only checks the length
532unsafe impl AnyBitPatternMarker for i8 {}
533// SAFETY: Any bit pattern is valid, so it is safe to implement `TrivialType` for this type
534unsafe impl TrivialType for i16 {
535    const ALIGNMENT: Alignment = Alignment::from_power(1)
536        .expect("Alignment of a primitive type is larger than `Alignment::MAX`");
537    const METADATA: &[u8] = &[IoTypeMetadataKind::I16 as u8];
538
539    #[inline(always)]
540    unsafe fn parse_step<const ALIGNED: bool>(bytes: &[u8]) -> Option<(&Unaligned<Self>, &[u8])> {
541        try_from_bytes_any_bit_pattern(bytes)
542    }
543}
544// SAFETY: Any bit pattern is a valid value of integers, the parsing step only checks the length
545unsafe impl AnyBitPatternMarker for i16 {}
546// SAFETY: Any bit pattern is valid, so it is safe to implement `TrivialType` for this type
547unsafe impl TrivialType for i32 {
548    const ALIGNMENT: Alignment = Alignment::from_power(2)
549        .expect("Alignment of a primitive type is larger than `Alignment::MAX`");
550    const METADATA: &[u8] = &[IoTypeMetadataKind::I32 as u8];
551
552    #[inline(always)]
553    unsafe fn parse_step<const ALIGNED: bool>(bytes: &[u8]) -> Option<(&Unaligned<Self>, &[u8])> {
554        try_from_bytes_any_bit_pattern(bytes)
555    }
556}
557// SAFETY: Any bit pattern is a valid value of integers, the parsing step only checks the length
558unsafe impl AnyBitPatternMarker for i32 {}
559// SAFETY: Any bit pattern is valid, so it is safe to implement `TrivialType` for this type
560unsafe impl TrivialType for i64 {
561    const ALIGNMENT: Alignment = Alignment::from_power(3)
562        .expect("Alignment of a primitive type is larger than `Alignment::MAX`");
563    const METADATA: &[u8] = &[IoTypeMetadataKind::I64 as u8];
564
565    #[inline(always)]
566    unsafe fn parse_step<const ALIGNED: bool>(bytes: &[u8]) -> Option<(&Unaligned<Self>, &[u8])> {
567        try_from_bytes_any_bit_pattern(bytes)
568    }
569}
570// SAFETY: Any bit pattern is a valid value of integers, the parsing step only checks the length
571unsafe impl AnyBitPatternMarker for i64 {}
572// SAFETY: Any bit pattern is valid, so it is safe to implement `TrivialType` for this type
573unsafe impl TrivialType for i128 {
574    // `Alignment::MAX` because native alignment for `i128` is 8 bytes (instead of 16) on 32-bit
575    // platforms
576    const ALIGNMENT: Alignment = Alignment::MAX;
577    const METADATA: &[u8] = &[IoTypeMetadataKind::I128 as u8];
578
579    #[inline(always)]
580    unsafe fn parse_step<const ALIGNED: bool>(bytes: &[u8]) -> Option<(&Unaligned<Self>, &[u8])> {
581        try_from_bytes_any_bit_pattern(bytes)
582    }
583}
584// SAFETY: Any bit pattern is a valid value of integers, the parsing step only checks the length
585unsafe impl AnyBitPatternMarker for i128 {}
586
587const fn array_metadata(size: u32, inner_metadata: &[u8]) -> ([u8; MAX_METADATA_CAPACITY], usize) {
588    concat_metadata_sources(&[
589        &[IoTypeMetadataKind::Array as u8],
590        &size.to_le_bytes(),
591        inner_metadata,
592    ])
593}
594
595// TODO: Change `usize` to `u32` once it is possible:
596//  https://github.com/rust-lang/rust/issues/156745
597// SAFETY: Elements follow each other without padding and are `TrivialType`, the parsing step checks
598// every element
599unsafe impl<const SIZE: usize, T> TrivialType for [T; SIZE]
600where
601    T: TrivialType,
602    [(); SUPPORTED_ARRAY::<T, SIZE>]:,
603{
604    const ALIGNMENT: Alignment = T::ALIGNMENT;
605    // Casting `SIZE` to `u32` is lossless, which is checked by the `SUPPORTED_ARRAY` bound
606    const METADATA: &[u8] = {
607        // The reference extends the lifetime of metadata scratch to that of the constant
608        let (metadata_scratch, metadata_size) = &array_metadata(SIZE as u32, T::METADATA);
609        metadata_scratch.split_at(*metadata_size).0
610    };
611
612    #[inline(always)]
613    unsafe fn parse_step<const ALIGNED: bool>(bytes: &[u8]) -> Option<(&Unaligned<Self>, &[u8])> {
614        let (bytes, remainder) = bytes.split_at_checked(size_of::<Self>())?;
615        // SAFETY: If `ALIGNED`, `bytes` are aligned for `Self` (function contract), which has the
616        // alignment of `T`
617        unsafe { try_skip_valid::<T, ALIGNED>(bytes, SIZE) }?;
618        // SAFETY: Elements follow each other without padding and each of them is a valid value as
619        // checked above, `Unaligned<Self>` has alignment 1 and the size of `Self`
620        let value = unsafe { bytes.as_ptr().cast::<Unaligned<Self>>().as_ref_unchecked() };
621        Some((value, remainder))
622    }
623}
624
625// SAFETY: Elements follow each other without padding, any bit pattern of each is a valid value,
626// which the parsing step of elements accepts. There is no array size limit here, `AnyBitPattern`
627// requires `[T; N]: TrivialType`, which has it.
628unsafe impl<const SIZE: usize, T> AnyBitPatternMarker for [T; SIZE] where T: AnyBitPatternMarker {}
629
630// SAFETY: All `TrivialType` instances are valid for `IoType`
631unsafe impl<T> IoType for T
632where
633    T: TrivialType,
634{
635    const METADATA: &[u8] = T::METADATA;
636
637    type PointerType = T;
638
639    type WithLifetime<'b> = T;
640
641    type Reborrowed<'b> = &'b mut T;
642
643    #[inline(always)]
644    fn size(&self) -> u32 {
645        T::SIZE
646    }
647
648    #[inline(always)]
649    fn capacity(&self) -> u32 {
650        self.size()
651    }
652
653    #[inline(always)]
654    #[track_caller]
655    unsafe fn set_size(&mut self, size: u32) {
656        debug_assert_eq!(size, T::SIZE, "`set_size` called with invalid input");
657    }
658
659    #[inline(always)]
660    #[track_caller]
661    unsafe fn from_ptr<'a>(
662        ptr: &'a NonNull<Self::PointerType>,
663        size: &'a u32,
664        capacity: u32,
665    ) -> impl Deref<Target = Self::WithLifetime<'a>> + 'a {
666        debug_assert!(ptr.is_aligned(), "Misaligned pointer");
667        debug_assert_eq!(*size, T::SIZE, "Invalid size");
668        debug_assert!(
669            *size <= capacity,
670            "Size {size} must not exceed capacity {capacity}"
671        );
672
673        // SAFETY: guaranteed by this function signature
674        unsafe { ptr.as_ref() }
675    }
676
677    #[inline(always)]
678    #[track_caller]
679    unsafe fn from_mut_ptr<'a>(
680        ptr: &'a mut NonNull<Self::PointerType>,
681        _size: &'a mut u32,
682        capacity: u32,
683    ) -> impl DerefMut<Target = Self::WithLifetime<'a>> + 'a {
684        debug_assert!(ptr.is_aligned(), "Misaligned pointer");
685        debug_assert!(
686            Self::SIZE <= capacity,
687            "Size {} must not exceed capacity {capacity}",
688            Self::SIZE
689        );
690
691        // SAFETY: guaranteed by this function signature
692        unsafe { ptr.as_mut() }
693    }
694
695    #[inline(always)]
696    #[track_caller]
697    unsafe fn try_from_ptr<'a>(
698        ptr: &'a NonNull<Self::PointerType>,
699        size: &'a u32,
700        capacity: u32,
701    ) -> Option<impl Deref<Target = Self::WithLifetime<'a>> + 'a> {
702        debug_assert!(ptr.is_aligned(), "Misaligned pointer");
703        debug_assert_eq!(*size, T::SIZE, "Invalid size");
704        debug_assert!(
705            *size <= capacity,
706            "Size {size} must not exceed capacity {capacity}"
707        );
708        // SAFETY: `ptr` is valid for reads of `size` bytes, which is the size of `T`, initialized
709        // and not written to during the call (function contract)
710        let bytes = unsafe { slice::from_raw_parts(ptr.as_ptr().cast::<u8>(), size_of::<T>()) };
711        // SAFETY: `ptr` is aligned for `T` (function contract)
712        unsafe { T::parse_step::<true>(bytes) }?;
713
714        // SAFETY: `size` is the size of `T` and doesn't exceed `capacity`, `ptr` is aligned and the
715        // memory is not written to while the returned value exists (function contract), and it
716        // holds a valid value of `T` as checked above
717        Some(unsafe { Self::from_ptr(ptr, size, capacity) })
718    }
719
720    #[inline(always)]
721    #[track_caller]
722    unsafe fn try_from_mut_ptr<'a>(
723        ptr: &'a mut NonNull<Self::PointerType>,
724        size: &'a mut u32,
725        capacity: u32,
726    ) -> Option<impl DerefMut<Target = Self::WithLifetime<'a>> + 'a> {
727        debug_assert!(ptr.is_aligned(), "Misaligned pointer");
728        debug_assert_eq!(*size, T::SIZE, "Invalid size");
729        debug_assert!(
730            *size <= capacity,
731            "Size {size} must not exceed capacity {capacity}"
732        );
733        // SAFETY: `ptr` is valid for reads of `size` bytes, which is the size of `T`, initialized
734        // and not accessed otherwise during the call (function contract), the slice is not used
735        // after parsing
736        let bytes = unsafe { slice::from_raw_parts(ptr.as_ptr().cast::<u8>(), size_of::<T>()) };
737        // SAFETY: `ptr` is aligned for `T` (function contract)
738        unsafe { T::parse_step::<true>(bytes) }?;
739
740        // SAFETY: `size` is the size of `T` and doesn't exceed `capacity`, `ptr` is aligned and the
741        // memory is not accessed otherwise while the returned value exists (function contract),
742        // and it holds a valid value of `T` as checked above
743        Some(unsafe { Self::from_mut_ptr(ptr, size, capacity) })
744    }
745
746    #[inline(always)]
747    fn as_ptr(&self) -> NonNull<Self::PointerType> {
748        NonNull::from_ref(self)
749    }
750
751    #[inline(always)]
752    fn as_mut_ptr(&mut self) -> NonNull<Self::PointerType> {
753        NonNull::from_mut(self)
754    }
755
756    #[inline(always)]
757    fn reborrow_mut(&mut self) -> Self::Reborrowed<'_> {
758        self
759    }
760}