feat(wasm): validate client event and state ABI
req: client_local/005\nreq: client_local/006\nreq: client_local/007\nreq: client_local/008\nreq: client_local/009\nreq: client_local/010\nreq: client_local/014
This commit is contained in:
+31
-6
@@ -89,14 +89,15 @@ pub fn handler(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
if !is_client {
|
||||
return quote!(#function).into();
|
||||
}
|
||||
if !function.sig.inputs.is_empty()
|
||||
let input_count = function.sig.inputs.len();
|
||||
if !matches!(input_count, 0 | 2)
|
||||
|| function.sig.asyncness.is_some()
|
||||
|| function.sig.unsafety.is_some()
|
||||
|| function.sig.constness.is_some()
|
||||
|| !function.sig.generics.params.is_empty()
|
||||
{
|
||||
let message = format!(
|
||||
"client-local hemx handler `{name}` must be a safe, synchronous, non-generic function with no parameters"
|
||||
"client-local hemx handler `{name}` must be safe, synchronous, non-generic, and accept either no parameters or `(hemx::wasm::ClientEvent, hemx::wasm::ClientState)`"
|
||||
);
|
||||
return quote!(
|
||||
#function
|
||||
@@ -108,6 +109,11 @@ pub fn handler(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
let function_name = &function.sig.ident;
|
||||
let export_name = format_ident!("__hemx_client_{function_name}");
|
||||
let export_module = format_ident!("__hemx_client_export_{function_name}");
|
||||
let invoke_handler = if input_count == 0 {
|
||||
quote!(super::#function_name())
|
||||
} else {
|
||||
quote!(super::#function_name(event, state))
|
||||
};
|
||||
quote!(
|
||||
#function
|
||||
|
||||
@@ -116,11 +122,30 @@ pub fn handler(attr: TokenStream, item: TokenStream) -> TokenStream {
|
||||
use ::hemx::wasm as wasm_bindgen;
|
||||
|
||||
#[::hemx::wasm::wasm_bindgen(js_name = #export_name)]
|
||||
pub fn invoke() -> ::std::vec::Vec<u8> {
|
||||
::hemx::wasm::encode_handler_effect(
|
||||
super::#function_name(),
|
||||
crate::ui::BUILD_FINGERPRINT,
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn invoke(
|
||||
event_version: u32,
|
||||
event_kind: ::std::string::String,
|
||||
event_value: ::std::option::Option<::std::string::String>,
|
||||
event_checked: ::std::option::Option<bool>,
|
||||
event_key: ::std::option::Option<::std::string::String>,
|
||||
state_version: u32,
|
||||
encoded_state: ::std::string::String,
|
||||
) -> ::std::result::Result<::std::vec::Vec<u8>, ::hemx::wasm::JsValue> {
|
||||
let (event, state) = ::hemx::wasm::decode_client_inputs(
|
||||
event_version,
|
||||
event_kind,
|
||||
event_value,
|
||||
event_checked,
|
||||
event_key,
|
||||
state_version,
|
||||
encoded_state,
|
||||
)
|
||||
.map_err(|error| ::hemx::wasm::JsValue::from_str(&error))?;
|
||||
Ok(::hemx::wasm::encode_handler_effect(
|
||||
#invoke_handler,
|
||||
crate::ui::BUILD_FINGERPRINT,
|
||||
))
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user