#[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 implementEncode::data_size()returning
DataSize::Fixed(n), then the type is also considered fixed-size.
Otherwise, the type isDataSize::Dynamic. -
fn size(&self) -> MSize
Computes the runtime-encoding size of the value by summing the sizes of all fields.
§What the macro generates
Given a struct like:
The macro expands into:
ⓘ
impl Encode for User {
const DATA_SIZE: DataSize = DataSize::Dynamic; // or DataSize::Fixed(n) if applicable
fn size(&self) -> MSize {
self.id.size() + self.name.size()
}
fn encode(&'_ self) -> std::borrow::Cow<'_, [u8]> {
let mut encoded = Vec::with_capacity(self.size() as usize);
encoded.extend_from_slice(&self.id.encode());
encoded.extend_from_slice(&self.name.encode());
std::borrow::Cow::Owned(encoded)
}
fn decode(data: std::borrow::Cow<[u8]>) -> ::ic_dbms_api::prelude::MemoryResult<Self> {
let mut offset = 0;
let id = Uint32::decode(std::borrow::Borrowed(&data[offset..]))?;
offset += id.size() as usize;
let name = Text::decode(std::borrow::Borrowed(&data[offset..]))?;
offset += name.size() as usize;
Ok(Self { id, name })
}
}§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
ic-dbms-canisterDBMS 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);