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;
forEach(ImmediateClosure::new_mut(&mut |val: JsValue| {
    sum += val.as_f64().unwrap() as i32;
}));
// 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_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 new_assert_unwind_safe when possible.

Source

pub fn new_assert_unwind_safe(f: &'a T) -> Self

Like new_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::new_assert_unwind_safe(&|| {
    println!("data len: {}", data.len());
});
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

pub fn new_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 new_mut_assert_unwind_safe when possible.

Source

pub fn new_mut_assert_unwind_safe(f: &'a mut T) -> Self

Like new_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::new_mut_assert_unwind_safe(&mut |x| {
    count += x;
});
Source

pub fn as_mut(self) -> ImmediateClosure<'a, T::AsMut>

Converts this closure to 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::new_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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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> ReturnWasmAbi for T
where T: IntoWasmAbi,

Source§

type Abi = <T as IntoWasmAbi>::Abi

Same as IntoWasmAbi::Abi
Source§

fn return_abi(self) -> <T as ReturnWasmAbi>::Abi

Same as IntoWasmAbi::into_abi, except that it may throw and never return in the case of Err.
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,