pub struct ImmediateClosure<'a, T: ?Sized> { /* private fields */ }Expand description
A closure wrapper for immediate/synchronous callbacks with unwind safety.
ImmediateClosure wraps a borrowed closure for use in synchronous JS callbacks
like Array.forEach, Array.map, etc. The JS side receives the closure,
calls it immediately, and discards it - no GC tracking is needed.
Panics are caught and converted to JavaScript exceptions (when built with
panic=unwind). No UnwindSafe bounds are required - the closure is wrapped
internally.
§Unwind Safety
ImmediateClosure provides unwind safety by catching panics and converting them
to JavaScript exceptions.
§Example
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern "C" {
fn forEach<'a>(cb: &ImmediateClosure<'a, dyn FnMut(JsValue) + 'a>);
}
let mut sum = 0;
let closure = ImmediateClosure::new_mut(&mut |val: JsValue| {
sum += val.as_f64().unwrap() as i32;
});
forEach(&closure);
// sum is now updatedNote: To ensure borrowed lifetimes are correctly inferred, make sure to pass the lifetime to both the ImmediateClosure lifetime parameter AND its dyn FnMut parameter, as in the example above.
Implementations§
Source§impl<'a, T: ?Sized + WasmClosure> ImmediateClosure<'a, T>
impl<'a, T: ?Sized + WasmClosure> ImmediateClosure<'a, T>
Sourcepub fn new<F>(f: &'a F) -> ImmediateClosure<'a, F::WithLifetime>where
F: IntoWasmClosureRef<'a, T> + ?Sized + MaybeUnwindSafe,
pub fn new<F>(f: &'a F) -> ImmediateClosure<'a, F::WithLifetime>where
F: IntoWasmClosureRef<'a, T> + ?Sized + MaybeUnwindSafe,
Creates an immediate closure from an immutable borrow of a Fn closure.
Immutable closures (Fn) are preferred because they are more likely to satisfy UnwindSafe
automatically. Use new_mut when you need to mutate captured state.
Note that immutable closures can be upcast() to mutable closures on the JS boundary
when required by function signatures.
Panics are caught as JS exceptions when building with panic=unwind.
The resulting closure can be upcasted to FnMut using upcast_ref.
§Example
let data = vec![1, 2, 3];
let closure = ImmediateClosure::new(&|| {
println!("data len: {}", data.len());
});
call_closure(&closure);Sourcepub fn new_mut<F>(f: &'a mut F) -> ImmediateClosure<'a, F::WithLifetime>where
F: IntoWasmClosureRefMut<'a, T> + ?Sized + MaybeUnwindSafe,
pub fn new_mut<F>(f: &'a mut F) -> ImmediateClosure<'a, F::WithLifetime>where
F: IntoWasmClosureRefMut<'a, T> + ?Sized + MaybeUnwindSafe,
Creates an immediate closure from a mutable borrow of a FnMut closure.
Use this for closures that need to mutate captured state. For closures that
don’t need mutation, new creates an immutable Fn closure
that is more likely to satisfy UnwindSafe automatically.
Panics are caught as JS exceptions when building with panic=unwind.
§Example
let mut count = 0;
let closure = ImmediateClosure::new_mut(&mut || { count += 1; });
call_closure(&closure);
assert_eq!(count, 1);Source§impl<'a, T: ?Sized + WasmClosure> ImmediateClosure<'a, T>
impl<'a, T: ?Sized + WasmClosure> ImmediateClosure<'a, T>
Sourcepub fn wrap_aborting(f: &'a T) -> Self
pub fn wrap_aborting(f: &'a T) -> Self
Like new, but does not catch panics.
This variant enables type inference from the expected type, since it takes the dyn type directly.
Note: Not unwind safe. Prefer new or
wrap_assert_unwind_safe when possible.
Sourcepub fn wrap_mut_aborting(f: &'a mut T) -> Self
pub fn wrap_mut_aborting(f: &'a mut T) -> Self
Like new_mut, but does not catch panics.
This variant enables type inference from the expected type, since it takes the dyn type directly.
Note: Not unwind safe. Prefer new_mut or
wrap_mut_assert_unwind_safe when possible.
Sourcepub fn wrap_assert_unwind_safe(f: &'a T) -> Self
pub fn wrap_assert_unwind_safe(f: &'a T) -> Self
Like wrap_aborting, but catches panics and converts them to JS exceptions.
Safety: Unwind safety is assumed when using this function, like using
AssertUnwindSafe(...), this must be verified explicitly.
§Example
let data = vec![1, 2, 3];
// Type is inferred from context
let closure: ImmediateClosure<dyn Fn()> = ImmediateClosure::wrap_assert_unwind_safe(&|| {
println!("data len: {}", data.len());
});Sourcepub fn wrap_mut_assert_unwind_safe(f: &'a mut T) -> Self
pub fn wrap_mut_assert_unwind_safe(f: &'a mut T) -> Self
Like wrap_mut_aborting, but catches panics and converts them to JS exceptions.
Safety: Unwind safety is assumed when using this function, like using
AssertUnwindSafe(...), this must be verified explicitly.
§Example
let mut count = 0;
// Type of `x` is inferred from context
let closure: ImmediateClosure<dyn FnMut(u32)> = ImmediateClosure::wrap_mut_assert_unwind_safe(&mut |x| {
count += x;
});Sourcepub fn as_mut(&self) -> &ImmediateClosure<'a, T::AsMut>
pub fn as_mut(&self) -> &ImmediateClosure<'a, T::AsMut>
Returns a reference to this closure as a mutable FnMut closure.
This is safe because every Fn can be called through a FnMut interface.
The fat pointer representation is compatible—&dyn Fn can be safely
reinterpreted as &dyn FnMut.
Note: Unlike ScopedClosure::as_mut, this only supports the Fn→FnMut conversion
with the same argument and return types. ImmediateClosure stores a Rust fat
pointer directly, so argument/return type variance is not possible.
§Example
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern "C" {
fn needs_fnmut(cb: &ImmediateClosure<dyn FnMut(u32)>);
}
let func: &dyn Fn(u32) = &|x| println!("{}", x);
let closure: ImmediateClosure<dyn Fn(u32)> = ImmediateClosure::wrap_assert_unwind_safe(func);
needs_fnmut(closure.as_mut());