Skip to main content

ImmediateClosure

Struct ImmediateClosure 

Source
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 updated

Note: 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>

Source

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);
Source

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>

Source

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.

Source

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.

Source

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());
});
Source

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;
});
Source

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());

Trait Implementations§

Source§

impl<T: ?Sized> Debug for ImmediateClosure<'_, T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'a, 'b, A, R> ErasableGeneric for ImmediateClosure<'a, dyn Fn(&A) -> R + 'b>

Source§

type Repr = &'static ImmediateClosure<'static, dyn Fn(<A as ErasableGeneric>::Repr) -> <R as ErasableGeneric>::Repr>

The singular concrete type that all generic variants can be transmuted on
Source§

impl<'a, 'b, R> ErasableGeneric for ImmediateClosure<'a, dyn Fn() -> R + 'b>
where R: ErasableGeneric,

Source§

type Repr = &'static ImmediateClosure<'static, dyn Fn() -> <R as ErasableGeneric>::Repr>

The singular concrete type that all generic variants can be transmuted on
Source§

impl<'a, 'b, A, R> ErasableGeneric for ImmediateClosure<'a, dyn Fn(A) -> R + 'b>

Source§

type Repr = &'static ImmediateClosure<'static, dyn Fn(<A as ErasableGeneric>::Repr) -> <R as ErasableGeneric>::Repr>

The singular concrete type that all generic variants can be transmuted on
Source§

impl<'a, 'b, A, B, R> ErasableGeneric for ImmediateClosure<'a, dyn Fn(A, B) -> R + 'b>

Source§

type Repr = &'static ImmediateClosure<'static, dyn Fn(<A as ErasableGeneric>::Repr, <B as ErasableGeneric>::Repr) -> <R as ErasableGeneric>::Repr>

The singular concrete type that all generic variants can be transmuted on
Source§

impl<'a, 'b, A, B, C, R> ErasableGeneric for ImmediateClosure<'a, dyn Fn(A, B, C) -> R + 'b>

Source§

type Repr = &'static ImmediateClosure<'static, dyn Fn(<A as ErasableGeneric>::Repr, <B as ErasableGeneric>::Repr, <C as ErasableGeneric>::Repr) -> <R as ErasableGeneric>::Repr>

The singular concrete type that all generic variants can be transmuted on
Source§

impl<'a, 'b, A, B, C, D, R> ErasableGeneric for ImmediateClosure<'a, dyn Fn(A, B, C, D) -> R + 'b>

Source§

type Repr = &'static ImmediateClosure<'static, dyn Fn(<A as ErasableGeneric>::Repr, <B as ErasableGeneric>::Repr, <C as ErasableGeneric>::Repr, <D as ErasableGeneric>::Repr) -> <R as ErasableGeneric>::Repr>

The singular concrete type that all generic variants can be transmuted on
Source§

impl<'a, 'b, A, B, C, D, E, R> ErasableGeneric for ImmediateClosure<'a, dyn Fn(A, B, C, D, E) -> R + 'b>

Source§

type Repr = &'static ImmediateClosure<'static, dyn Fn(<A as ErasableGeneric>::Repr, <B as ErasableGeneric>::Repr, <C as ErasableGeneric>::Repr, <D as ErasableGeneric>::Repr, <E as ErasableGeneric>::Repr) -> <R as ErasableGeneric>::Repr>

The singular concrete type that all generic variants can be transmuted on
Source§

impl<'a, 'b, A, B, C, D, E, F, R> ErasableGeneric for ImmediateClosure<'a, dyn Fn(A, B, C, D, E, F) -> R + 'b>

Source§

type Repr = &'static ImmediateClosure<'static, dyn Fn(<A as ErasableGeneric>::Repr, <B as ErasableGeneric>::Repr, <C as ErasableGeneric>::Repr, <D as ErasableGeneric>::Repr, <E as ErasableGeneric>::Repr, <F as ErasableGeneric>::Repr) -> <R as ErasableGeneric>::Repr>

The singular concrete type that all generic variants can be transmuted on
Source§

impl<'a, 'b, A, B, C, D, E, F, G, R> ErasableGeneric for ImmediateClosure<'a, dyn Fn(A, B, C, D, E, F, G) -> R + 'b>

Source§

type Repr = &'static ImmediateClosure<'static, dyn Fn(<A as ErasableGeneric>::Repr, <B as ErasableGeneric>::Repr, <C as ErasableGeneric>::Repr, <D as ErasableGeneric>::Repr, <E as ErasableGeneric>::Repr, <F as ErasableGeneric>::Repr, <G as ErasableGeneric>::Repr) -> <R as ErasableGeneric>::Repr>

The singular concrete type that all generic variants can be transmuted on
Source§

impl<'a, 'b, A, B, C, D, E, F, G, H, R> ErasableGeneric for ImmediateClosure<'a, dyn Fn(A, B, C, D, E, F, G, H) -> R + 'b>

Source§

type Repr = &'static ImmediateClosure<'static, dyn Fn(<A as ErasableGeneric>::Repr, <B as ErasableGeneric>::Repr, <C as ErasableGeneric>::Repr, <D as ErasableGeneric>::Repr, <E as ErasableGeneric>::Repr, <F as ErasableGeneric>::Repr, <G as ErasableGeneric>::Repr, <H as ErasableGeneric>::Repr) -> <R as ErasableGeneric>::Repr>

The singular concrete type that all generic variants can be transmuted on
Source§

impl<'a, 'b, A, R> ErasableGeneric for ImmediateClosure<'a, dyn FnMut(&A) -> R + 'b>

Source§

type Repr = &'static ImmediateClosure<'static, dyn FnMut(<A as ErasableGeneric>::Repr) -> <R as ErasableGeneric>::Repr>

The singular concrete type that all generic variants can be transmuted on
Source§

impl<'a, 'b, R> ErasableGeneric for ImmediateClosure<'a, dyn FnMut() -> R + 'b>
where R: ErasableGeneric,

Source§

type Repr = &'static ImmediateClosure<'static, dyn FnMut() -> <R as ErasableGeneric>::Repr>

The singular concrete type that all generic variants can be transmuted on
Source§

impl<'a, 'b, A, R> ErasableGeneric for ImmediateClosure<'a, dyn FnMut(A) -> R + 'b>

Source§

type Repr = &'static ImmediateClosure<'static, dyn FnMut(<A as ErasableGeneric>::Repr) -> <R as ErasableGeneric>::Repr>

The singular concrete type that all generic variants can be transmuted on
Source§

impl<'a, 'b, A, B, R> ErasableGeneric for ImmediateClosure<'a, dyn FnMut(A, B) -> R + 'b>

Source§

type Repr = &'static ImmediateClosure<'static, dyn FnMut(<A as ErasableGeneric>::Repr, <B as ErasableGeneric>::Repr) -> <R as ErasableGeneric>::Repr>

The singular concrete type that all generic variants can be transmuted on
Source§

impl<'a, 'b, A, B, C, R> ErasableGeneric for ImmediateClosure<'a, dyn FnMut(A, B, C) -> R + 'b>

Source§

type Repr = &'static ImmediateClosure<'static, dyn FnMut(<A as ErasableGeneric>::Repr, <B as ErasableGeneric>::Repr, <C as ErasableGeneric>::Repr) -> <R as ErasableGeneric>::Repr>

The singular concrete type that all generic variants can be transmuted on
Source§

impl<'a, 'b, A, B, C, D, R> ErasableGeneric for ImmediateClosure<'a, dyn FnMut(A, B, C, D) -> R + 'b>

Source§

type Repr = &'static ImmediateClosure<'static, dyn FnMut(<A as ErasableGeneric>::Repr, <B as ErasableGeneric>::Repr, <C as ErasableGeneric>::Repr, <D as ErasableGeneric>::Repr) -> <R as ErasableGeneric>::Repr>

The singular concrete type that all generic variants can be transmuted on
Source§

impl<'a, 'b, A, B, C, D, E, R> ErasableGeneric for ImmediateClosure<'a, dyn FnMut(A, B, C, D, E) -> R + 'b>

Source§

type Repr = &'static ImmediateClosure<'static, dyn FnMut(<A as ErasableGeneric>::Repr, <B as ErasableGeneric>::Repr, <C as ErasableGeneric>::Repr, <D as ErasableGeneric>::Repr, <E as ErasableGeneric>::Repr) -> <R as ErasableGeneric>::Repr>

The singular concrete type that all generic variants can be transmuted on
Source§

impl<'a, 'b, A, B, C, D, E, F, R> ErasableGeneric for ImmediateClosure<'a, dyn FnMut(A, B, C, D, E, F) -> R + 'b>

Source§

type Repr = &'static ImmediateClosure<'static, dyn FnMut(<A as ErasableGeneric>::Repr, <B as ErasableGeneric>::Repr, <C as ErasableGeneric>::Repr, <D as ErasableGeneric>::Repr, <E as ErasableGeneric>::Repr, <F as ErasableGeneric>::Repr) -> <R as ErasableGeneric>::Repr>

The singular concrete type that all generic variants can be transmuted on
Source§

impl<'a, 'b, A, B, C, D, E, F, G, R> ErasableGeneric for ImmediateClosure<'a, dyn FnMut(A, B, C, D, E, F, G) -> R + 'b>

Source§

type Repr = &'static ImmediateClosure<'static, dyn FnMut(<A as ErasableGeneric>::Repr, <B as ErasableGeneric>::Repr, <C as ErasableGeneric>::Repr, <D as ErasableGeneric>::Repr, <E as ErasableGeneric>::Repr, <F as ErasableGeneric>::Repr, <G as ErasableGeneric>::Repr) -> <R as ErasableGeneric>::Repr>

The singular concrete type that all generic variants can be transmuted on
Source§

impl<'a, 'b, A, B, C, D, E, F, G, H, R> ErasableGeneric for ImmediateClosure<'a, dyn FnMut(A, B, C, D, E, F, G, H) -> R + 'b>

Source§

type Repr = &'static ImmediateClosure<'static, dyn FnMut(<A as ErasableGeneric>::Repr, <B as ErasableGeneric>::Repr, <C as ErasableGeneric>::Repr, <D as ErasableGeneric>::Repr, <E as ErasableGeneric>::Repr, <F as ErasableGeneric>::Repr, <G as ErasableGeneric>::Repr, <H as ErasableGeneric>::Repr) -> <R as ErasableGeneric>::Repr>

The singular concrete type that all generic variants can be transmuted on
Source§

impl<T> IntoWasmAbi for &ImmediateClosure<'_, T>
where T: WasmClosure + ?Sized,

Source§

type Abi = WasmSlice

The Wasm ABI type that this converts into when crossing the ABI boundary.
Source§

fn into_abi(self) -> WasmSlice

Convert self into Self::Abi so that it can be sent across the wasm ABI boundary.
Source§

impl<T> OptionIntoWasmAbi for &ImmediateClosure<'_, T>
where T: WasmClosure + ?Sized,

Source§

fn none() -> WasmSlice

Returns an ABI instance indicating “none”, which JS will interpret as the None branch of this option. Read more
Source§

impl<'a, 'b, T1, T2> UpcastFrom<ImmediateClosure<'a, T1>> for ImmediateClosure<'b, T2>
where T1: ?Sized + WasmClosure, T2: ?Sized + WasmClosure + UpcastFrom<T1>,

Auto Trait Implementations§

§

impl<'a, T> Freeze for ImmediateClosure<'a, T>
where T: ?Sized,

§

impl<'a, T> RefUnwindSafe for ImmediateClosure<'a, T>
where T: RefUnwindSafe + ?Sized,

§

impl<'a, T> Send for ImmediateClosure<'a, T>
where T: Send + ?Sized,

§

impl<'a, T> Sync for ImmediateClosure<'a, T>
where T: Sync + ?Sized,

§

impl<'a, T> Unpin for ImmediateClosure<'a, T>
where T: ?Sized,

§

impl<'a, T> UnsafeUnpin for ImmediateClosure<'a, T>
where T: ?Sized,

§

impl<'a, T> !UnwindSafe for ImmediateClosure<'a, T>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<S, T> Upcast<T> for S
where T: UpcastFrom<S> + ?Sized, S: ?Sized,

Source§

fn upcast(&self) -> &T
where Self: ErasableGeneric, T: Sized + ErasableGeneric<Repr = <Self as ErasableGeneric>::Repr>,

Perform a zero-cost type-safe upcast to a wider ref type within the Wasm bindgen generics type system. Read more
Source§

fn upcast_into(self) -> T
where Self: Sized + ErasableGeneric, T: Sized + ErasableGeneric<Repr = <Self as ErasableGeneric>::Repr>,

Perform a zero-cost type-safe upcast to a wider type within the Wasm bindgen generics type system. Read more
Source§

impl<T> VectorFromWasmAbi for T
where T: ErasableGeneric<Repr = JsValue> + WasmDescribe,

Source§

impl<T> VectorIntoWasmAbi for T
where T: ErasableGeneric<Repr = JsValue> + WasmDescribe,