Macro gstd::metadata

source ·
macro_rules! metadata {
    ($arg:expr) => { ... };
}
Expand description

Provide information about input and output types as the metadata.

Metadata can be used as a message payload description for external tools and applications that interact with Gear programs in the network. For example, in https://idea.gear-tech.io, it correctly forms a message payload from JSON on the JS application side.

This macro contains input and output message types for init, handle, and async functions. It also contains the state output type used when reading some part of the program’s state.

Examples

Define six custom types for input/output and provide information about them as the metadata:

use gstd::{metadata, msg, prelude::*};

#[derive(Decode, Encode, TypeInfo)]
#[codec(crate = gstd::codec)]
struct InitInput {
    field: String,
}

#[derive(Decode, Encode, TypeInfo)]
#[codec(crate = gstd::codec)]
struct InitOutput {
    field: String,
}

#[derive(Decode, Encode, TypeInfo)]
#[codec(crate = gstd::codec)]
struct Input {
    field: String,
}

#[derive(Decode, Encode, TypeInfo)]
#[codec(crate = gstd::codec)]
struct Output {
    field: String,
}

#[derive(Decode, Encode, TypeInfo)]
#[codec(crate = gstd::codec)]
struct StateInput {
    threshold: i32,
}

#[derive(Decode, Encode, TypeInfo)]
#[codec(crate = gstd::codec)]
enum StateOutput {
    Small(i32),
    Big(i32),
}

metadata! {
    title: "App",
    init:
        input: InitInput,
        output: InitOutput,
    handle:
        input: Input,
        output: Output,
    state:
        input: StateInput,
        output: StateOutput,
}

static mut STATE: i32 = 0;

#[no_mangle]
extern "C" fn init() {
    let InitInput { field } = msg::load().expect("Unable to load");
    let output = InitOutput { field };
    msg::reply(output, 0).expect("Unable to reply");
}

#[no_mangle]
extern "C" fn handle() {
    let Input { field } = msg::load().expect("Unable to load");
    unsafe { STATE = 1000 };
    let output = Output { field };
    msg::reply(output, 0).expect("Unable to reply");
}

#[no_mangle]
extern "C" fn meta_state() -> *mut [i32; 2] {
    let StateInput { threshold } = msg::load().expect("Unable to load");
    let state = unsafe { STATE };
    let result = if state > threshold {
        StateOutput::Big(state)
    } else {
        StateOutput::Small(state)
    };
    gstd::util::to_leak_ptr(result.encode())
}