Skip to main content

Encode

Derive Macro Encode 

Source
#[derive(Encode)]
Expand description

Automatically implements the Encode trait for a struct.

This derive macro generates two methods required by the Encode trait:

  • fn data_size() -> DataSize Computes the static size of the encoded type. If all fields implement Encode::data_size() returning DataSize::Fixed(n), then the type is also considered fixed-size. Otherwise, the type is DataSize::Dynamic.

  • fn size(&self) -> MSize Computes the runtime-encoding size of the value by summing the sizes of all fields, saturating at MSize::MAX when the sum does not fit.

§What the macro generates

Given a struct like:

ⓘ
#[derive(Encode)]
struct User {
    id: Uint32,
    name: Text,
}

The macro expands into:

ⓘ
impl Encode for User {
    const DATA_SIZE: DataSize = DataSize::Dynamic; // or DataSize::Fixed(n) if applicable

    fn size(&self) -> MSize {
        MSize::MIN.saturating_add(self.id.size()).saturating_add(self.name.size())
    }

    fn encode(&'_ self) -> std::borrow::Cow<'_, [u8]> {
        let mut __wasm_dbms_encoded = Vec::with_capacity(self.size() as usize);
        __wasm_dbms_encoded.extend_from_slice(&self.id.encode());
        __wasm_dbms_encoded.extend_from_slice(&self.name.encode());
        std::borrow::Cow::Owned(__wasm_dbms_encoded)
    }

    fn decode(__wasm_dbms_data: std::borrow::Cow<[u8]>) -> ::wasm_dbms_api::prelude::MemoryResult<Self> {
        let mut __wasm_dbms_offset = 0;
        let id = Uint32::decode(std::borrow::Borrowed(&__wasm_dbms_data[__wasm_dbms_offset..]))?;
        __wasm_dbms_offset += id.size() as usize;
        let name = Text::decode(std::borrow::Borrowed(&__wasm_dbms_data[__wasm_dbms_offset..]))?;
        __wasm_dbms_offset += name.size() as usize;
        Ok(Self { id, name })
    }
}

§Zero-size structs

A struct without fields (struct Empty {} or struct Empty;) encodes to zero bytes: SIZE is DataSize::Fixed(0) and ALIGNMENT is 1. A fixed-size struct is otherwise aligned to its size; whenever that size is 0 (e.g. only zero-size fields) the alignment is 1, so storage never divides by a zero alignment.

§Requirements

  • Each field type must implement Encode.
  • Only works on structs; enums and unions are not supported.
  • All field identifiers must be valid Rust identifiers (no tuple structs).

§Notes

  • It is intended for internal use within the wasm-dbms DBMS memory system.

§Errors

The macro will fail to expand if:

  • The struct has unnamed fields (tuple struct)
  • A field type does not implement Encode
  • The macro is applied to a non-struct item.

§Example

ⓘ
#[derive(Encode, Debug, PartialEq, Eq)]
struct Position {
    x: Int32,
    y: Int32,
}

let pos = Position { x: 10.into(), y: 20.into() };
assert_eq!(Position::data_size(), DataSize::Fixed(8));
assert_eq!(pos.size(), 8);
let encoded = pos.encode();
let decoded = Position::decode(encoded).unwrap();
assert_eq!(pos, decoded);