zng

Macro clmv

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

Clone move closure.

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

§Examples

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

fn foo(mut f: impl FnMut(bool) + 'static) {
    f(true);
}

let bar = "Cool!".to_owned();
foo(clmv!(bar, |p| {
    if p { println!("cloned: {bar}") }
}));

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

Expands to:

foo({
    let bar = bar.clone();
    move |p| {
        if p { 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.

fn foo(mut f: impl FnMut(bool) + 'static) {
    f(true);
}

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

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

Expands to:

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

§Async

See async_clmv_fn! for creating async closures or async_clmv! for creating clone move futures.