Skip to main content

transforms

Attribute Macro transforms 

Source
#[transforms]
Expand description

Generates a unit struct with inherent upcast and current_version functions from annotated transform functions.

§Attributes

  • aggregate = Type — the aggregate type these transforms belong to
  • error = Type — the error type returned by transform functions

Each method must be annotated with #[transform(...)]:

  • event = "EventName" — the event type this transform handles
  • from = N — source schema version (>= 1)
  • to = N — target schema version (must be from + 1)
  • rename = "NewName" — optional event type rename

§Compile-time validation

  • from >= 1
  • to == from + 1 for each transform (contiguity per step)
  • No duplicate (event, from) pairs
  • Chain coverage: for each event type, every schema version in [1, current_version] is reachable via a contiguous chain — gaps produce a compile error naming the missing step

§Emitted output

The macro emits a pub struct <Name>; plus an inherent impl block carrying the user’s transform functions (with #[transform] attrs stripped) and two associated functions:

  • pub fn upcast<'a>(EventMorsel<'a>) -> Result<EventMorsel<'a>, Error> — runs the chain to current schema version. Associated (no &self) so call sites are OrderTransforms::upcast(morsel) — a 'static function pointer pluggable into [EventStore::load_with].
  • pub fn current_version(event_type: &str) -> Option<Version> — the write-path schema-version stamp lookup. Also associated; call as OrderTransforms::current_version("EventName").

§Example

#[mnesis::transforms(aggregate = Order, error = MyError)]
impl OrderTransforms {
    #[transform(event = "OrderCreated", from = 1, to = 2)]
    fn v1_to_v2(payload: &[u8]) -> Result<Vec<u8>, MyError> {
        Ok(payload.to_vec())
    }
}

// Direct call:
let upgraded = OrderTransforms::upcast(morsel)?;

// Plugged into the facade:
let root = store.load_with(id, OrderTransforms::upcast).await?;