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 14 methods // Required method fn try_from_bytes_unaligned( bytes: &[u8], ) -> Option<(&Unaligned<Self>, &[u8])>; // 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_read_unaligned(bytes: &[u8]) -> Option<(Self, &[u8])> { ... } final fn try_read_unaligned_exact(bytes: &[u8]) -> Option<Self> { ... } final unsafe fn read_unaligned(bytes: &[u8]) -> Option<Self> { ... } final unsafe fn read_unaligned_unchecked(bytes: &[u8]) -> Self { ... } final unsafe fn from_bytes(bytes: &[u8]) -> Option<&Self> { ... } final unsafe fn from_bytes_unchecked(bytes: &[u8]) -> &Self { ... } final unsafe fn from_bytes_mut(bytes: &mut [u8]) -> Option<&mut Self> { ... } final unsafe fn from_bytes_mut_unchecked(bytes: &mut [u8]) -> &mut Self { ... } final fn as_bytes(&self) -> &[u8; _] { ... } final unsafe fn as_bytes_mut(&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 Self::try_from_bytes_unaligned() checks that they are a valid value of the type, which is a length check for types that accept every bit pattern (see AnyBitPattern).

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>()
  • Self::try_from_bytes_unaligned() 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

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 = _

Required Methods§

Source

fn try_from_bytes_unaligned(bytes: &[u8]) -> Option<(&Unaligned<Self>, &[u8])>

Parse the beginning of bytes, which don’t need to be aligned.

Returns the value and the remaining bytes, or None if bytes are shorter than the type or don’t start with a valid value. #[derive(TrivialType)] implements it, the other parsing methods are built on it.

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_read_unaligned(bytes: &[u8]) -> Option<(Self, &[u8])>

Read a copy from the beginning of bytes, which don’t need to be aligned, returns the value and the remaining bytes

Source

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

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

Source

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

Read unaligned value from memory.

Returns None if the number of input bytes is not sufficient to represent the type. Prefer Self::try_read_unaligned(), which checks the bytes.

§Safety

bytes start with a valid value of Self (see TrivialType), for example bytes that Self::try_read_unaligned() accepts.

Source

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

Similar to Self::read_unaligned(), but doesn’t do any checks at all.

§Safety

bytes start with a valid value of Self.

Source

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

Create a reference to a type, which is represented by provided memory.

Memory must be correctly aligned, or else None will be returned. Size must be sufficient, padding beyond the size of the type is allowed. Prefer Self::try_from_bytes(), which checks the bytes.

§Safety

bytes start with a valid value of Self (see TrivialType), for example bytes that Self::try_from_bytes() accepts.

Source

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

Similar to Self::from_bytes(), but doesn’t do any checks at all.

§Safety

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

Source

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

Create a mutable reference to a type, which is represented by provided memory.

Memory must be correctly aligned, or else None will be returned. Size must be sufficient, padding beyond the size of the type is allowed. Prefer Self::try_from_bytes_mut(), which checks the bytes.

§Safety

bytes start with a valid value of Self (see TrivialType), for example bytes that Self::try_from_bytes_mut() accepts.

Source

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

Similar to Self::from_bytes_mut(), but doesn’t do any checks at all.

§Safety

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

Source

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

Access the underlying byte representation of a data structure

Source

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

Access the underlying mutable byte representation of a data structure.

§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§

fn try_from_bytes_unaligned(bytes: &[u8]) -> Option<(&Unaligned<Self>, &[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§

fn try_from_bytes_unaligned(bytes: &[u8]) -> Option<(&Unaligned<Self>, &[u8])>

Source§

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

Source§

const ALIGNMENT: Alignment = T::ALIGNMENT

Source§

const METADATA: &[u8]

Source§

fn try_from_bytes_unaligned(bytes: &[u8]) -> Option<(&Unaligned<Self>, &[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]