Derive Macro sewup_derive::Table

source · []
#[derive(Table)]
{
    // Attributes available to this derive:
    #[belongs_to]
    #[belongs_none_or]
}
Expand description

provides the handers for CRUD and the Protocol struct to communicate with these handlers.

use sewup_derive::Table;
#[derive(Table)]
struct Person {
    trusted: bool,
    age: u8,
}

The crud handlers are generated as {struct_name}::get, {struct_name}::create, {struct_name}::update, {struct_name}::delete, you can easily used these handlers as following example.

#[ewasm_main]
fn main() -> Result<()> {
    let mut contract = Contract::new()?;

    match contract.get_function_selector()? {
        ewasm_fn_sig!(person::get) => ewasm_input_from!(contract move person::get)?,
        ewasm_fn_sig!(person::create) => ewasm_input_from!(contract move person::create)?,
        ewasm_fn_sig!(person::update) => ewasm_input_from!(contract move person::update)?,
        ewasm_fn_sig!(person::delete) => ewasm_input_from!(contract move person::delete)?,
        _ => return Err(RDBError::UnknownHandle.into()),
    }

    Ok(())
}

The protocol is the input and also the output format of these handlers, besides these handlers are easy to build by the {struct_name}::protocol, {struct_name}::Protocol, and use set_id for specify the record you want to modify. for examples.

let handler_input = person::protocol(person);
let mut default_person_input: person::Protocol = Person::default().into();
default_input.set_id(2);

you can use ewasm_output_from! to get the exactly input/output binary of the protol, for example:

let handler_input = person::protocol(person);
ewasm_output_from!(handler_input)

Please note that the protocol default and the protocol for default instance may be different. This base on the implementation of the default trait of the structure.

let default_input = person::Protocol::default();
let default_person_input: person::Protocol = Person::default().into();
assert!(default_input != default_person_input)

The relation can be set with #[belongs_to(Person)] or #[belongs_none_or(Person)]

#[derive(Table, Default, Clone, PartialEq, Serialize, Deserialize)]
#[belongs_none_or(Location)]
pub struct Person {
    pub trusted: bool,
    pub age: u8,
    pub location_id: Option<usize>,
}

#[derive(Table, Default, Clone, PartialEq, Serialize, Deserialize)]
#[belongs_to(Person)]
pub struct Post {
    pub content: SizedString!(50),

    // Currently, this field need to set up manually, this will be enhance later
    pub person_id: usize,
}

#[derive(Table, Default, Clone, PartialEq, Serialize, Deserialize)]
pub struct Location {
    pub address: Raw,
}

After the directive setup, you can use table_name.another_table_name to get the related instance, for example

let person: Person = post.person()?;
let home: Option<Location> = person.location()?;