Skip to main content

Module enum_byte

Module enum_byte 

Source
Expand description

Unit enums in zero-copy layouts and instruction arguments.

A Rust enum is not Pod: a #[repr(u8)] enum with three variants has 253 byte values that are not a valid value of the type, so overlaying it on account bytes is undefined behaviour the moment an account holds one of them. The usual workaround is a bare u8 field and a hand-written match, which loses the type in the layout and lets a handler forget the validation.

EnumByte<E> is the field type instead: one byte, alignment 1, every bit pattern valid as far as memory safety goes, and the enum recovered through EnumByte::get, which refuses a byte that names no variant. #[hopper::unit_enum] implements UnitEnum for a fieldless enum, so the mapping between variants and bytes is generated, not written.

ⓘ
#[hopper::unit_enum]
pub enum Status {
    Open = 1,
    Settled = 2,
    Cancelled = 3,
}

#[hopper::state(disc = 5, version = 1)]
#[derive(Clone, Copy)]
#[repr(C)]
pub struct Order {
    pub maker: Address,
    pub status: EnumByte<Status>,
}

if order.status.get()? == Status::Open {
    order.status.set(Status::Settled);
}

Structs§

EnumByte
One byte that stores a UnitEnum. Pod, so it can sit in a #[hopper::state] layout, a #[hopper::pod] struct, or #[hopper::args]; the enum is validated when it is read.

Traits§

UnitEnum
A fieldless enum with a one-byte representation. Implemented by #[hopper::unit_enum]; hand-written impls must keep from_byte the exact inverse of to_byte on every variant.