testnumbat_wasm/io/
dyn_arg.rs

1use crate::{
2    api::{ErrorApi, ManagedTypeApi},
3    signal_arg_de_error, ArgId, DynArgInput,
4};
5use testnumbat_codec::*;
6
7/// Any type that is used as an endpoint argument must implement this trait.
8pub trait DynArg: Sized {
9    fn dyn_load<I: DynArgInput>(loader: &mut I, arg_id: ArgId) -> Self;
10}
11
12/// All top-deserializable types can be endpoint arguments.
13impl<T> DynArg for T
14where
15    T: TopEncode + TopDecode,
16{
17    fn dyn_load<I: DynArgInput>(loader: &mut I, arg_id: ArgId) -> Self {
18        if let TypeInfo::Unit = <T as TopDecode>::TYPE_INFO {
19            // unit type returns without loading anything
20            let cast_unit: T = unsafe { core::mem::transmute_copy(&()) };
21            return cast_unit;
22        }
23
24        let dyn_arg_vm_api = loader.dyn_arg_vm_api();
25        let arg_input = loader.next_arg_input();
26        T::top_decode_or_exit(arg_input, (dyn_arg_vm_api, arg_id), dyn_load_exit)
27    }
28}
29
30#[inline(always)]
31fn dyn_load_exit<EA>(ctx: (EA, ArgId), de_err: DecodeError) -> !
32where
33    EA: ErrorApi + ManagedTypeApi,
34{
35    let (api, arg_id) = ctx;
36    signal_arg_de_error(api, arg_id, de_err)
37}