#variables #closures #clone #block #move #async #macro

macro autoclone

A simple macro to clone variables before passing them into a move closure or async block

3 releases

0.1.3 Dec 28, 2024
0.1.2 Dec 28, 2024
0.1.1 Dec 27, 2024

#371 in Procedural macros

Download history 393/week @ 2024-12-25 41/week @ 2025-01-01

434 downloads per month
Used in 3 crates (2 directly)

MIT license

15KB
336 lines

A simple macro to clone variables before passing them into a move closure or async block.


lib.rs:

A simple macro to clone variables before passing them into a move closure or async block.

Usage

The list of variables to clone is defined at the beginning of the block, which is easier to add cloning for variables.

With autoclone:

#[autoclone]
fn test() {
    let my_string = "Hello, World!".to_string();
    let callback = move || {
        // Declare variables that need cloning.
        // `autoclone!(<my_variabke>, <other_variabke>, ...);`
        // Just remove the `autoclone!(...);` statement if cloning is not required.
        autoclone!(my_string);
        println!("Inside the move callback: {my_string}");
    };
    println!("Outside the move callback: {my_string}");
    callback();
}

Comparison with clone-macro

With clone-macro:

fn test() {
    let my_string = "Hello, World!".to_string();
    // Adding cloning is not trivial
    // - requires adding/removing `clone!([my_string]` if cloning is necessary
    // - requires adding/removing the corresponding closing `)`
    let callback = clone!([my_string], move || {
        println!("Inside the move callback: {my_string}");
    });
    println!("Outside the move callback: {my_string}");
    callback();
}

See also https://docs.rs/clone-macro

Syntax sugar

The autoclone!() macro does not exist. Instead, the #[autoclone] proc macro modifies the code. You can see the modified code using #[autoclone(debug = true)]

The previous example expands to

fn test() {
    let my_string = "Hello, World!".to_string();
    let callback = {
        let my_string = my_string.to_owned();
        move || {
            println!("Inside the move callback: {my_string}");
        }
    };
    println!("Outside the move callback: {my_string}");
    callback();
}

Dependencies

~0.8–1.3MB
~29K SLoC