|
| 1 | +use wasm_bindgen::prelude::*; |
| 2 | + |
| 3 | +macro_rules! define_react_use_state_for_type { |
| 4 | + ( value: $type_value:ty, $($t:tt)+ ) => { |
| 5 | + define_react_use_state_for_type!( |
| 6 | + input: $type_value, |
| 7 | + output: $type_value, |
| 8 | + $($t)+ |
| 9 | + ); |
| 10 | + }; |
| 11 | + ( |
| 12 | + input: $type_input:ty, |
| 13 | + output: $type_output:ty, |
| 14 | + object: $name_object:ident, |
| 15 | + setter: $name_setter:ident, |
| 16 | + use_state: $name_use:ident, |
| 17 | + use_state_with: $name_use_with:ident, |
| 18 | + auto_clean: $name_clean:ident, |
| 19 | + auto_clean_with: $name_clean_with:ident |
| 20 | + $(,)? |
| 21 | + ) => { |
| 22 | + #[derive(Debug, Clone)] |
| 23 | + pub type $name_object; |
| 24 | + #[wasm_bindgen(structural, method, getter)] |
| 25 | + fn value(this: &$name_object) -> $type_output; |
| 26 | + #[wasm_bindgen(structural, method, getter)] |
| 27 | + fn setter(this: &$name_object) -> $name_setter; |
| 28 | + |
| 29 | + #[derive(Debug, Clone)] |
| 30 | + pub type $name_setter; |
| 31 | + #[wasm_bindgen(structural, method)] |
| 32 | + fn set_state(this: &$name_setter, value: $type_input); |
| 33 | + /// Closure `get_value_from_old` will be called immediately, |
| 34 | + /// thus it is safe to use reference here |
| 35 | + /// |
| 36 | + /// Closure get_value_from_old will be called only once |
| 37 | + #[wasm_bindgen(structural, method, js_name = "set_state")] |
| 38 | + fn set_state_with( |
| 39 | + this: &$name_setter, |
| 40 | + get_value_from_old: &mut dyn FnMut($type_output) -> $type_input, |
| 41 | + ); |
| 42 | + |
| 43 | + #[wasm_bindgen(js_name = "use_state_object")] |
| 44 | + fn $name_use(initial_value: $type_input) -> $name_object; |
| 45 | + |
| 46 | + #[wasm_bindgen(js_name = "use_state_object")] |
| 47 | + fn $name_use_with( |
| 48 | + initial_value: &mut dyn FnMut() -> $type_input, |
| 49 | + ) -> $name_object; |
| 50 | + |
| 51 | + #[wasm_bindgen(js_name = "use_state_auto_clean")] |
| 52 | + fn $name_clean( |
| 53 | + initial_value: $type_input, |
| 54 | + free: &Closure<dyn FnMut($type_output)>, |
| 55 | + ) -> $name_object; |
| 56 | + |
| 57 | + #[wasm_bindgen(js_name = "use_state_auto_clean")] |
| 58 | + fn $name_clean_with( |
| 59 | + get_initial_value: &mut dyn FnMut() -> $type_input, |
| 60 | + free: &Closure<dyn FnMut($type_output)>, |
| 61 | + ) -> $name_object; |
| 62 | + }; |
| 63 | +} |
| 64 | + |
| 65 | +// #[cfg_attr( |
| 66 | +// feature = "import-react", |
| 67 | +// wasm_bindgen(inline_js = r#" |
| 68 | +// import * as React from "react"; |
| 69 | +// export function use_state_object(initial_value) { |
| 70 | +// const [state, set_state] = React.useState(initial_value); |
| 71 | +// return { value: state, setter: { set_state } }; |
| 72 | +// } |
| 73 | +// export function use_state_auto_clean(initial_value, clean) { |
| 74 | +// const obj = use_state_object(initial_value); |
| 75 | +// const state = obj.value; |
| 76 | +// React.useEffect(() => { clean(state) }, [state]); |
| 77 | +// } |
| 78 | +// "#) |
| 79 | +// )] |
| 80 | +// #[cfg_attr( |
| 81 | +// not(feature = "import-react"), |
| 82 | +// wasm_bindgen(inline_js = r#" |
| 83 | +// export function use_state_object(initial_value) { |
| 84 | +// const [state, set_state] = React.useState(initial_value); |
| 85 | +// return { value: state, setter: { set_state } }; |
| 86 | +// } |
| 87 | +// export function use_state_auto_clean(initial_value, clean) { |
| 88 | +// const obj = use_state_object(initial_value); |
| 89 | +// const state = obj.value; |
| 90 | +// React.useEffect(() => { clean(state) }, [state]); |
| 91 | +// } |
| 92 | +// "#) |
| 93 | +// )] |
| 94 | + |
| 95 | +macro_rules! ttt { |
| 96 | + () => { |
| 97 | + type Element; |
| 98 | + }; |
| 99 | +} |
| 100 | + |
| 101 | +#[wasm_bindgen] |
| 102 | +extern "C" { |
| 103 | + define_react_use_state_for_type! { |
| 104 | + value: usize, |
| 105 | + object: UseStateUsizeObject, |
| 106 | + setter: UseStateUsizeObjectSetter, |
| 107 | + use_state: use_state_object_usize, |
| 108 | + use_state_with: use_state_object_usize_with, |
| 109 | + auto_clean: use_state_usize_auto_clean, |
| 110 | + auto_clean_with: use_state_usize_auto_clean_with, |
| 111 | + } |
| 112 | +} |
0 commit comments