numbat_wasm/io/
dyn_arg.rs

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