Attribute Macro brush_lang::modifiers
source · [−]#[modifiers]
Expand description
Macro calls every modifier function by passing self and the code of function’s body. It means that modifiers must be available in the scope of the marked method.
Modifiers are designed to be used for methods in impl sections.
The method can have several modifiers. They will be expanded from left to right.
The modifier can accept arguments from the scope of the method definition
(you can pass an argument from the signature of marked method or from the outside scope of function).
The modifier accepts arguments only by value and the type of argument must support Clone
trait,
because macro will clone the argument and will pass it to the modifier.
Explanation:
Let’s define next modifiers.
#[brush::modifier_definition]
fn A<T>(instance: &T, body: impl FnOnce(&T) -> &'static str) -> &'static str {
println!("A before");
let result = body(instance);
println!("A after");
result
}
#[brush::modifier_definition]
fn B<T, F: FnOnce(&T) -> &'static str>(instance: &T, body: F, data1: u8, data2: u8) -> &'static str {
println!("B before {} {}", data1, data2);
let result = body(instance);
println!("B after {} {}", data1, data2);
result
}
#[brush::modifier_definition]
fn C<T, F>(instance: &T, body: F) -> &'static str
where F: FnOnce(&T) -> &'static str
{
println!("C before");
let result = body(instance);
println!("C after");
result
}
struct Contract {}
impl Contract {
#[brush::modifiers(A, B(_data, 13), C)]
fn main_logic(&self, _data: u8) -> &'static str {
return "Return value";
}
}
The code above will be expanded into:
#[brush::modifier_definition]
fn A<T>(instance: &T, body: impl FnOnce(&T) -> &'static str) -> &'static str {
println!("A before");
let result = body(instance);
println!("A after");
result
}
#[brush::modifier_definition]
fn B<T, F: FnOnce(&T) -> &'static str>(instance: &T, body: F, data1: u8, data2: u8) -> &'static str {
println!("B before {} {}", data1, data2);
let result = body(instance);
println!("B after {} {}", data1, data2);
result
}
#[brush::modifier_definition]
fn C<T, F>(instance: &T, body: F) -> &'static str
where F: FnOnce(&T) -> &'static str
{
println!("C before");
let result = body(instance);
println!("C after");
result
}
struct Contract {}
impl Contract {
fn main_logic(&self, _data: u8) -> &'static str {
let mut __brush_body_2 = |__brush_instance_modifier: &Self| {
let __brush_cloned_0 = _data.clone();
let __brush_cloned_1 = 13.clone();
let mut __brush_body_1 = |__brush_instance_modifier: &Self| {
let mut __brush_body_0 = |__brush_instance_modifier: &Self| return "Return value";;
C(__brush_instance_modifier, __brush_body_0)
};
B(__brush_instance_modifier, __brush_body_1, __brush_cloned_0, __brush_cloned_1)
};
A(self, __brush_body_2)
}
}
Example: Usage
#[brush::contract]
mod example {
#[ink(storage)]
#[derive(Default)]
pub struct Contract {
initialized: bool,
owner: AccountId,
}
#[brush::modifier_definition]
fn once(instance: &mut Contract, body: impl FnOnce(&mut Contract)) {
assert!(!instance.initialized, "Contract is already initialized");
body(instance);
instance.initialized = true;
}
impl Contract {
#[ink(constructor)]
pub fn new() -> Self {
Self::default()
}
#[ink(message)]
#[brush::modifiers(once)]
pub fn init(&mut self, owner: AccountId) {
self.owner = owner;
}
}
}