web3api_wasm_rs/
invoke.rs

1use crate::malloc::alloc;
2
3#[link(wasm_import_module = "w3")]
4extern "C" {
5    /// Get Invoke Arguments
6    #[link_name = "__w3_invoke_args"]
7    pub fn __w3_invoke_args(method_ptr: u32, args_ptr: u32);
8
9    /// Set Invoke Result
10    #[link_name = "__w3_invoke_result"]
11    pub fn __w3_invoke_result(ptr: u32, len: u32);
12
13    /// Set Invoke Error
14    #[link_name = "__w3_invoke_error"]
15    pub fn __w3_invoke_error(ptr: u32, len: u32);
16}
17
18/// Keep track of all invokable functions
19pub type InvokeFunction = fn(args_buf: &[u8]) -> Vec<u8>;
20
21pub struct InvokeArgs {
22    pub method: String,
23    pub args: Vec<u8>,
24}
25
26/// Helper for fetching invoke args
27pub fn w3_invoke_args(method_size: u32, args_size: u32) -> InvokeArgs {
28    let method_size_ptr = alloc(method_size as usize);
29    let args_size_ptr = alloc(args_size as usize);
30
31    unsafe { __w3_invoke_args(method_size_ptr as u32, args_size_ptr as u32) };
32
33    let method = unsafe {
34        String::from_raw_parts(method_size_ptr, method_size as usize, method_size as usize)
35    };
36    let args =
37        unsafe { Vec::from_raw_parts(args_size_ptr, args_size as usize, args_size as usize) };
38
39    InvokeArgs { method, args }
40}
41
42/// Helper for handling `_w3_invoke`
43pub fn w3_invoke(args: InvokeArgs, opt_invoke_func: Option<InvokeFunction>) -> bool {
44    match opt_invoke_func {
45        Some(func) => {
46            let result = func(args.args.as_slice());
47            let res_len = result.len() as u32;
48            unsafe { __w3_invoke_result(result.as_ptr() as u32, res_len) };
49            true
50        }
51        None => {
52            let message = format!("Could not find invoke function {}", &args.method);
53            let msg_bytes = message.as_bytes();
54            let msg_len = msg_bytes.len() as u32;
55            unsafe { __w3_invoke_error(msg_bytes.as_ptr() as u32, msg_len) };
56            false
57        }
58    }
59}