Skip to main content

with

Macro with 

Source
macro_rules! with {
    (move |$cx:ident| $body:expr) => { ... };
    (|$cx:ident| $body:expr) => { ... };
    (move |_| $body:expr) => { ... };
    (|_| $body:expr) => { ... };
    (move |$cx:ident| -> $ret:ty $body:block) => { ... };
    (|$cx:ident| -> $ret:ty $body:block) => { ... };
    (move |_| -> $ret:ty $body:block) => { ... };
    (|_| -> $ret:ty $body:block) => { ... };
}
Expand description

Wraps a closure that will be lazily evaluated when TryIntoJs::try_into_js is called.

Useful for executing arbitrary code on the main thread before returning from a function exported with neon::export.

The value of the body is converted with TryIntoJs, following the same rules as the return value of an exported function — e.g., Err becomes a JavaScript exception.

§Example

#[neon::export(task)]
fn sum(nums: Vec<f64>) -> impl for<'cx> TryIntoJs<'cx> {
    let sum = nums.into_iter().sum::<f64>();

    extract::with!(move |cx| cx.number(sum))
}

Ordinary closure capture rules apply: move gives the closure ownership of the variables it captures (sum above) and is required when the closure outlives the enclosing function, as it does when returned from an exported function.

Fallible bodies may use ?. Annotate the closure’s return type to name the error type:

use std::time::Instant;

#[neon::export(task)]
fn sum(nums: Vec<f64>) -> impl for<'cx> TryIntoJs<'cx> {
    let start = Instant::now();
    let sum = nums.into_iter().sum::<f64>();
    let log = format!("sum took {} ms", start.elapsed().as_millis());

    extract::with!(move |cx| -> NeonResult<_> {
        cx.global::<JsObject>("console")?
            .method(cx, "log")?
            .arg(&log)?
            .exec()?;

        Ok(sum)
    })
}