gmeta_codegen

Attribute Macro metawasm

Source
#[metawasm]
Expand description

Generates metawasm functions.

An example of the expected structure:

use gstd::prelude::*;

#[derive(Decode, Encode, TypeInfo)]
pub struct StateType;

#[derive(Encode, TypeInfo)]
pub struct SomeReturnType;

#[derive(Decode, TypeInfo)]
pub struct SomeArg;

#[gmeta::metawasm]
pub mod metafns {
    pub type State = StateType;

    /// Documentation...
    pub fn some_function(_: State) -> SomeReturnType {
        unimplemented!()
    }

    pub fn another_function_but_with_arg(mut _state: State, _arg: SomeArg) -> State {
        unimplemented!()
    }

    /// Another doc...
    pub fn function_with_multiple_args(
        _state: State,
        mut _arg1: SomeArg,
        _arg2: u16,
        mut _arg3: u32,
    ) -> SomeReturnType {
        unimplemented!()
    }
}

§Syntax

  • This attribute must be used on the public mod container with the metafns identifier.
  • The first item in the module must be a public type alias with the State identifier. The type for which State will be an alias must implement Decode trait.

Usually the state type should be imported from the implemented associated Metadata::State type from the program’s io crate.

  • The rest of items must be public functions.
  • The first argument’s type of metafunctions must be State.
  • If the first argument uses the identifier pattern, the identifier must be state or _state.

In addition to the mandatory first argument, functions can have additional ones.

  • The maximum amount of additional arguments is 18 due restrictions of the SCALE codec.
  • All additional arguments must implement the Decode & TypeInfo traits.
  • A function mustn’t return () or nothing.
  • A returned type must implement the Encode & TypeInfo traits.

§Expansion result

This attribute doesn’t change the metafns module and items inside, but adds use super::*; inside the module because, in most cases, it’ll be useful for importing items from an upper namespace. So every item in the same namespace where the module is located is accessible inside it.

The rest of the magic happens in the another generated private extern module. It registers all metawasm functions, their arguments & return types, and generates extern functions with the same names. Later, they can be called from a metaWASM binary inside a blockchain.

Important note: although metafunctions can take more than 1 additional arguments, on the metaWASM binary level, they must be passed as one. So if the amount of additional arguments is 0 or 1, nothing needs to be changed, but if more - they all must be placed inside a tuple in the same order as in their function’s signature.

E.g., argument definitions for the above example:

  • For some_function an argument must be None.
  • For another_function_but_with_arg an argument must be Some(SomeArg).
  • For function_with_multiple_args an argument must be Some((SomeArg, u16, u32)).