Crate autoclone

Source
Expand description

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_variable>, <other_variable>, ...);`
        // 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();
}

Attribute Macros§

autoclone
A simple macro to cloning variable before passing them into a move closure or async block.