#[macro_export]
macro_rules! temp_make_event {
($name:ident, $type:literal => $event:path) => {
pub struct $name {
event: $event,
}
impl dominator::traits::StaticEvent for $name {
const EVENT_TYPE: &'static str = $type;
#[inline]
fn unchecked_from_event(event: web_sys::Event) -> Self {
use wasm_bindgen::JsCast;
Self {
event: event.unchecked_into(),
}
}
}
impl $name {
#[inline]
pub fn prevent_default(&self) {
self.event.prevent_default();
}
#[inline]
pub fn target(&self) -> Option<web_sys::EventTarget> {
self.event.target()
}
#[inline]
pub fn dyn_target<A>(&self) -> Option<A>
where
A: wasm_bindgen::JsCast,
{
use wasm_bindgen::JsCast;
self.target()?.dyn_into().ok()
}
}
};
}
temp_make_event!(Message, "message" => web_sys::MessageEvent);
impl Message {
pub fn try_serde_data<T: serde::de::DeserializeOwned>(
&self,
) -> Result<T, serde_wasm_bindgen::Error> {
serde_wasm_bindgen::from_value(self.event.data())
}
pub fn serde_data_unchecked<T: serde::de::DeserializeOwned>(&self) -> T {
use wasm_bindgen::UnwrapThrowExt;
self.try_serde_data().unwrap_throw()
}
}
temp_make_event!(Load, "load" => web_sys::Event);
#[macro_export]
macro_rules! make_custom_event {
($name:ident, $type:literal) => {
$crate::temp_make_event!($name, $type => web_sys::CustomEvent);
impl $name {
pub fn detail(&self) -> JsValue { self.event.detail() }
}
}
}
#[macro_export]
macro_rules! make_custom_event_serde {
($type:literal, $name:ident, $data:ident) => {
$crate::make_custom_event!($name, $type);
impl $name {
pub fn try_data(&self) -> Result<$data, serde_wasm_bindgen::Error> {
serde_wasm_bindgen::from_value(self.detail())
}
pub fn data(&self) -> $data {
use wasm_bindgen::UnwrapThrowExt;
serde_wasm_bindgen::from_value(self.detail()).unwrap_throw()
}
}
};
}
#[macro_export]
macro_rules! make_ts_event {
($literal:literal, $data:ident) => {
paste::item! {
$crate::make_custom_event_serde!($literal, [<$data Event>], $data);
cfg_if::cfg_if! {
if #[cfg(feature = "ts_test")] {
use web_sys::CustomEvent;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn [<check_rust_event_ $data>](event:CustomEvent) -> Result<JsValue, JsValue> {
let literal = event.type_();
let event:[<$data Event>] = unsafe {
std::mem::transmute::<CustomEvent, [<$data Event>]>(event)
};
if literal == $literal {
let data:$data = event.serde_data_unchecked();
let expected = serde_json::to_string(&$data::default()).unwrap_throw();
let got = serde_json::to_string(&data).unwrap_throw();
if expected != got {
Err(JsValue::from_str(&format!("did not match default! should be {} but is {}", expected, got)))
} else {
Ok(JsValue::from_str(&got))
}
} else {
Err(JsValue::from_str(&format!("wrong type! should be {} but is {}", $literal, literal)))
}
}
}
}
}
}
}