Skip to main content

TrivialType

Trait TrivialType 

Source
pub unsafe trait TrivialType
where Self: Copy + 'static,
{ const ALIGNMENT: Alignment; const METADATA: &[u8]; const SIZE: u32 = _;
Show 16 methods // Provided methods final fn try_from_bytes(bytes: &[u8]) -> Option<(&Self, &[u8])> { ... } final fn try_from_bytes_exact(bytes: &[u8]) -> Option<&Self> { ... } final fn try_from_bytes_mut( bytes: &mut [u8], ) -> Option<(&mut Self, &mut [u8])> { ... } final fn try_from_bytes_mut_exact(bytes: &mut [u8]) -> Option<&mut Self> { ... } final fn from_bytes(bytes: &[u8]) -> Option<(&Self, &[u8])> where Self: AnyBitPattern { ... } final fn from_bytes_exact(bytes: &[u8]) -> Option<&Self> where Self: AnyBitPattern { ... } final unsafe fn from_bytes_unchecked(bytes: &[u8]) -> &Self { ... } final fn from_bytes_mut(bytes: &mut [u8]) -> Option<(&mut Self, &mut [u8])> where Self: AnyBitPattern { ... } final fn from_bytes_mut_exact(bytes: &mut [u8]) -> Option<&mut Self> where Self: AnyBitPattern { ... } final unsafe fn from_bytes_mut_unchecked(bytes: &mut [u8]) -> &mut Self { ... } final fn slice_from_bytes( bytes: &[u8], count: usize, ) -> Option<(&[Self], &[u8])> where Self: AnyBitPattern { ... } final fn slice_from_bytes_mut( bytes: &mut [u8], count: usize, ) -> Option<(&mut [Self], &mut [u8])> where Self: AnyBitPattern { ... } final fn as_bytes(&self) -> &[u8; _] { ... } final fn slice_as_bytes(values: &[Self]) -> &[u8] ⓘ { ... } final fn as_bytes_mut(&mut self) -> &mut [u8; _] where Self: AnyBitPattern { ... } final unsafe fn as_bytes_mut_unchecked(&mut self) -> &mut [u8; _] { ... }
}
Expand description

Simple wrapper data type that is designed in such a way that its serialization/deserialization is the same as the type itself.

Serialization takes the bytes of a value. Deserialization parses bytes: the parsing step checks that they are a valid value of the type, which is a length check for types that accept every bit pattern (see AnyBitPattern). Bytes that are not aligned for the type are parsed with the methods of Unaligned, like Unaligned::<T>::try_from_bytes().

A valid value is one whose every field is a valid value of its type, like 0 or 1 for a bool and the index of a variant for the discriminant of an enum, and that satisfies the invariants unsafe code relies on. Parsing may reject more, like a length of FixedCapacityElements above its capacity, but doesn’t check encoding rules, like the bytes of its length prefix after the length.

§Safety

  • There is no padding, every byte is initialized and there is no interior mutability
  • The alignment is at most Alignment::MAX
  • Self::SIZE is not overridden
  • Self::ALIGNMENT is the alignment that Self::METADATA decodes to, and it is at least align_of::<Self>()
  • The parsing step parse_step::<ALIGNED>() returns Some((value, remainder)) only if bytes start with size_of::<Self>() bytes that are a valid value of Self, value points to the beginning of bytes and remainder is the rest of bytes after those bytes. This holds for both flavours: the aligned one (ALIGNED is true) gets bytes aligned for Self, the unaligned one gets bytes of any alignment

Implementations are expected to be composites of existing TrivialTypes without custom alignment, whose alignment is then at most Alignment::MAX as well. Prefer #[derive(TrivialType)], which upholds this contract.

§Deriving

#[derive(TrivialType)] supports structs and enums and checks the following requirements at compile time:

  • no generic parameters, and types of all fields implement TrivialType
  • structs are #[repr(C)] or #[repr(transparent)] without other options
  • enums are #[repr(u8)] without other options
  • no #[repr(align(N))] or #[repr(packed)] in any #[repr(..)] attribute, Unaligned can be used to reduce the alignment of a field to one byte instead
  • no implicit padding, explicit padding: [u8; N] fields can be added where necessary. Padding is determined by TrivialType::ALIGNMENT of the field types. Each variant of an enum is laid out like a #[repr(C)] struct with the discriminant as the first field, so fields of all variants must have the same total size
  • explicit discriminants of enum variants are equal to the index of the variant, metadata identifies variants by their index and doesn’t record discriminants
  • at most 255 fields in a struct or enum variant and at most 255 variants in an enum, names of the type, its fields and variants are at most 255 bytes long
  • size is smaller than 2^32 bytes
  • metadata, including metadata of field types, is at most MAX_METADATA_CAPACITY bytes, otherwise const evaluation panics with an opaque error
  • structs parse their fields in order, enums check the discriminant and parse the fields of that variant
  • deriving means that any combination of valid field values is a valid value of the type, private fields and #[non_exhaustive] included, because parsing creates values without calling constructors, unless #[trivial_type(validate = path)] rejects it
  • structs implement AnyBitPatternMarker when all their fields do, unless they use #[trivial_type(validate = path)]

Invariants that unsafe code relies on are checked with #[trivial_type(validate = path)]. path is called as path(value: &Self) -> bool after all fields were parsed and must return false for every value that unsafe code relying on the invariants can’t handle. It must not panic, since parsing is used in code that is verified not to panic, and a const fn is recommended, the derive may become const later. Such types don’t implement AnyBitPatternMarker.

It is called by every parsing method, including those of arrays of the type, of Unaligned and of containers through IoType::try_from_ptr() and IoType::try_from_mut_ptr(). The unsafe methods that skip parsing, IoType::from_ptr(), IoType::from_mut_ptr() and derives of other crates, like SCALE’s Decode and serde’s Deserialize, don’t call it.

Required Associated Constants§

Source

const ALIGNMENT: Alignment

Alignment of the type in metadata.

Integers and bool are aligned to their size, () and Unaligned to 1 byte, other types to the largest alignment of their contents. It is never smaller than align_of::<Self>(), so memory aligned to it is aligned for Self.

Source

const METADATA: &[u8]

Data structure metadata in binary form, describing shape and types of the contents, see IoTypeMetadataKind for encoding details.

Provided Associated Constants§

Source

const SIZE: u32 = _

Provided Methods§

Source

final fn try_from_bytes(bytes: &[u8]) -> Option<(&Self, &[u8])>

Parse the beginning of aligned bytes, returns the value and the remaining bytes.

Returns None if bytes are not aligned for Self, are too short or don’t start with a valid value.

Source

final fn try_from_bytes_exact(bytes: &[u8]) -> Option<&Self>

Like Self::try_from_bytes(), but returns None if there are more bytes than the value

Source

final fn try_from_bytes_mut(bytes: &mut [u8]) -> Option<(&mut Self, &mut [u8])>

Like Self::try_from_bytes(), but returns an exclusive reference.

Only valid values of Self can be written through it, so the bytes stay a valid value.

Source

final fn try_from_bytes_mut_exact(bytes: &mut [u8]) -> Option<&mut Self>

Like Self::try_from_bytes_mut(), but returns None if there are more bytes than the value

Source

final fn from_bytes(bytes: &[u8]) -> Option<(&Self, &[u8])>
where Self: AnyBitPattern,

Create a reference to a value at the beginning of aligned bytes, returns the value and the remaining bytes.

Returns None if bytes are not aligned for Self or are too short. Unlike Self::try_from_bytes() it doesn’t parse the bytes, since any bytes are a valid value.

Source

final fn from_bytes_exact(bytes: &[u8]) -> Option<&Self>
where Self: AnyBitPattern,

Like Self::from_bytes(), but returns None if there are more bytes than the value

Source

final unsafe fn from_bytes_unchecked(bytes: &[u8]) -> &Self

Similar to Self::from_bytes(), but for any type and without any checks

§Safety

bytes are aligned for Self and start with a valid value of Self.

Source

final fn from_bytes_mut(bytes: &mut [u8]) -> Option<(&mut Self, &mut [u8])>
where Self: AnyBitPattern,

Like Self::from_bytes(), but returns an exclusive reference

Source

final fn from_bytes_mut_exact(bytes: &mut [u8]) -> Option<&mut Self>
where Self: AnyBitPattern,

Like Self::from_bytes_mut(), but returns None if there are more bytes than the value

Source

final unsafe fn from_bytes_mut_unchecked(bytes: &mut [u8]) -> &mut Self

Similar to Self::from_bytes_mut(), but for any type and without any checks

§Safety

bytes are aligned for Self and start with a valid value of Self.

Source

final fn slice_from_bytes( bytes: &[u8], count: usize, ) -> Option<(&[Self], &[u8])>
where Self: AnyBitPattern,

Create a slice of count values at the beginning of aligned bytes, returns the values and the remaining bytes.

Returns None if bytes are not aligned for Self or are too short. Like Self::from_bytes() it doesn’t parse the bytes, since any bytes are a valid value.

Source

final fn slice_from_bytes_mut( bytes: &mut [u8], count: usize, ) -> Option<(&mut [Self], &mut [u8])>
where Self: AnyBitPattern,

Like Self::slice_from_bytes(), but returns an exclusive reference

Source

final fn as_bytes(&self) -> &[u8; _]

Access the underlying byte representation of a data structure

Source

final fn slice_as_bytes(values: &[Self]) -> &[u8] ⓘ

Access the underlying byte representation of a slice of values

Source

final fn as_bytes_mut(&mut self) -> &mut [u8; _]
where Self: AnyBitPattern,

Access the underlying mutable byte representation of a data structure

Source

final unsafe fn as_bytes_mut_unchecked(&mut self) -> &mut [u8; _]

Similar to Self::as_bytes_mut(), but for any type.

§Safety

Only bytes of a valid value of Self may be written to the returned array.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementations on Foreign Types§

Source§

impl TrivialType for ()

Source§

impl TrivialType for bool

Source§

impl TrivialType for i8

Source§

impl TrivialType for i16

Source§

impl TrivialType for i32

Source§

impl TrivialType for i64

Source§

impl TrivialType for i128

Source§

const ALIGNMENT: Alignment = Alignment::MAX

Source§

const METADATA: &[u8]

Source§

impl TrivialType for u8

Source§

impl TrivialType for u16

Source§

impl TrivialType for u32

Source§

impl TrivialType for u64

Source§

impl TrivialType for u128

Source§

const ALIGNMENT: Alignment = Alignment::MAX

Source§

const METADATA: &[u8]

Source§

impl<const SIZE: usize, T> TrivialType for [T; SIZE]
where T: TrivialType, [(); _]:,

Source§

const ALIGNMENT: Alignment = T::ALIGNMENT

Source§

const METADATA: &[u8]

Implementors§

Source§

impl<Data> TrivialType for Unaligned<Data>
where Data: TrivialType,

Source§

const ALIGNMENT: Alignment = u8::ALIGNMENT

Source§

const METADATA: &[u8]

Source§

impl<Element, const CAPACITY: usize> TrivialType for FixedCapacityElements<Element, CAPACITY>
where Element: TrivialType, [(); _]:,

Source§

const ALIGNMENT: Alignment = Element::ALIGNMENT

Source§

const METADATA: &[u8]

Source§

impl<const CAPACITY: usize> TrivialType for FixedCapacityString<CAPACITY>
where [(); _]:,

Source§

const ALIGNMENT: Alignment = FixedCapacityElements<u8, CAPACITY>::ALIGNMENT

Source§

const METADATA: &[u8]