zng

Macro async_clmv

source
macro_rules! async_clmv {
    ($($tt:tt)+) => { ... };
}
Expand description

Async clone move block.

This macro is similar to clmv!, but creates a future instead of a closure.

A common pattern when creating 'static futures is to capture clones by move, this way the future is 'static and the cloned values are still available after creating the future. This macro facilitates this pattern.

§Examples

In the example bar is clone-moved into the 'static future given to foo.

async fn foo(mut f: impl Future<Output=()> + 'static) {
    f.await;
}

let bar = "Cool!".to_owned();
foo(async_clmv!(bar, {
    deadline(100.ms()).await;
    println!("cloned: {bar}")
}));

println!("original: {bar}");

Expands to:

foo({
    let bar = bar.clone();
    async move {
        deadline(100.ms()).await;
        println!("cloned: {bar}")
    }
});

§Other Patterns

Sometimes you want to clone an inner deref of the value, or you want the clone to be mut, you can annotate the variables cloned to achieve these effects.

async fn foo(mut f: impl Future<Output=()> + 'static) {
    f.await;
}

let bar = Arc::new("Cool!".to_string());
foo(async_clmv!(mut *bar, {
    bar.push_str("!");
    println!("cloned String not Arc: {bar}");
}));

println!("original: {bar}");

Expands to:

foo({
    let mut bar = (*bar).clone();
    async move {
        bar.push_str("!");
        println!("cloned String not Arc: {bar}")
    }
});