[][src]Struct wasm_bindgen::closure::Closure

pub struct Closure<T: ?Sized> { /* fields omitted */ }

A handle to both a closure in Rust as well as JS closure which will invoke the Rust closure.

A Closure is the primary way that a 'static lifetime closure is transferred from Rust to JS. Closure currently requires that the closures it's created with have the 'static lifetime in Rust for soundness reasons.

This type is a "handle" in the sense that whenever it is dropped it will invalidate the JS closure that it refers to. Any usage of the closure in JS after the Closure has been dropped will raise an exception. It's then up to you to arrange for Closure to be properly deallocate at an appropriate location in your program.

The type parameter on Closure is the type of closure that this represents. Currently this can only be the Fn and FnMut traits with up to 7 arguments (and an optional return value). The arguments/return value of the trait must be numbers like u32 for now, although this restriction may be lifted in the future!

Example

Sample usage of Closure to invoke the setTimeout API.

#[wasm_bindgen]
extern "C" {
    fn setTimeout(closure: &Closure<FnMut()>, time: u32);

    #[wasm_bindgen(js_namespace = console)]
    fn log(s: &str);
}

#[wasm_bindgen]
pub struct ClosureHandle(Closure<FnMut()>);

#[wasm_bindgen]
pub fn run() -> ClosureHandle {
    // First up we use `Closure::wrap` to wrap up a Rust closure and create
    // a JS closure.
    let cb = Closure::wrap(Box::new(move || {
        log("timeout elapsed!");
    }) as Box<FnMut()>);

    // Next we pass this via reference to the `setTimeout` function, and
    // `setTimeout` gets a handle to the corresponding JS closure.
    setTimeout(&cb, 1_000);

    // If we were to drop `cb` here it would cause an exception to be raised
    // when the timeout elapses. Instead we *return* our handle back to JS
    // so JS can tell us later when it would like to deallocate this handle.
    ClosureHandle(cb)
}

Sample usage of the same example as above except using web_sys instead

extern crate wasm_bindgen;
extern crate web_sys;

use wasm_bindgen::JsCast;

#[wasm_bindgen]
pub struct ClosureHandle(Closure<FnMut()>);

#[wasm_bindgen]
pub fn run() -> ClosureHandle {
    let cb = Closure::wrap(Box::new(move || {
        web_sys::console::log_1(&"timeout elapsed!".into());
    }) as Box<FnMut()>);

    let window = web_sys::window().unwrap();
    window.set_timeout_with_callback_and_timeout_and_arguments_0(
        // Note this method call, which uses `as_ref()` to get a `JsValue`
        // from our `Closure` which is then converted to a `&Function`
        // using the `JsCast::unchecked_ref` function.
        cb.as_ref().unchecked_ref(),
        1_000,
    );

    // same as above
    ClosureHandle(cb)
}

Methods

impl<T: ?Sized> Closure<T> where
    T: WasmClosure, 
[src]

pub fn wrap(data: Box<T>) -> Closure<T>[src]

A mostly internal function to wrap a boxed closure inside a Closure type.

This is the function where the JS closure is manufactured.

pub fn forget(self)[src]

Leaks this Closure to ensure it remains valid for the duration of the entire program.

Note: this function will leak memory. It should be used sparingly to ensure the memory leak doesn't affect the program too much.

When a Closure is dropped it will invalidate the associated JS closure, but this isn't always desired. Some callbacks are alive for the entire duration of the program, so this can be used to conveniently leak this instance of Closure while performing as much internal cleanup as it can.

Trait Implementations

impl<'a, T: ?Sized> IntoWasmAbi for &'a Closure<T> where
    T: WasmClosure, 
[src]

type Abi = u32

The wasm ABI type that this converts into when crossing the ABI boundary. Read more

impl<T> Drop for Closure<T> where
    T: ?Sized
[src]

impl<T: ?Sized> AsRef<JsValue> for Closure<T>[src]

Auto Trait Implementations

impl<T> !Send for Closure<T>

impl<T> !Sync for Closure<T>

Blanket Implementations

impl<T> From for T[src]

impl<T, U> TryFrom for T where
    U: Into<T>, 
[src]

type Error = !

🔬 This is a nightly-only experimental API. (try_from)

The type returned in the event of a conversion error.

impl<T, U> TryInto for T where
    U: TryFrom<T>, 
[src]

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

🔬 This is a nightly-only experimental API. (try_from)

The type returned in the event of a conversion error.

impl<T, U> Into for T where
    U: From<T>, 
[src]

impl<T> Borrow for T where
    T: ?Sized
[src]

impl<T> BorrowMut for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]