#closures #binding #clone #capture

macro bind

Proc macro for binding values into an expression (usually a closure)

2 releases

0.1.1 Jan 10, 2024
0.1.0 Jan 8, 2024

#1929 in Procedural macros

Used in heartless_tk


177 lines

This crate provides a proc macro to generate "let bindings" automatically, usually cloning values into an expression(usually a closure). Inspired by crate enclose.


bind!( ( comma_separated_list_of_var_bindings ) the_expr_that_uses_the_vars )

comma_separated_list_of_var_bindings is in the form of var_binding, another var_binding, ....

var_binding is in the form of:

  1. id, generating let id = id.clone();

  2. mut id, generating let mut id = id.clone();

  3. new_id = id, generating let new_id = id.clone();

  4. mut new_id = id, generating let mut new_id = id.clone();

  5. id = expr, generating let id = expr;

  6. mut id = expr, generating let mut id = expr;

  7. expr, generating let the_only_id_in_the_expr = expr;, e.g. bind!( (s.to_owned()) .. ) generates let s = s.to_owned().

  8. mut expr, generating let mut the_only_id_in_the_expr = expr; e.g. bind!( (mut s.to_owned()) .. ) generates let mut s = s.to_owned().


Why This Project

Sometimes we are forced to write some boring code like:

let foo2 = foo.clone();
let bar2 = *bar;
let baz2 = baz.to_owned();
let f = move |args| {
    // access to foo2, bar2 and baz2

It's quite annoying, messing up the source code and the readers can't focus on business logic. Some crates have been published to dealing with this, and the bind crate is yet another one, inspired by crate enclose, which provides a convenient declarative macro. Since crate bind is a proc_macro, it can do more than macro_rules.


let f = bind!( ( foo,*bar,baz.to_owned() )
    move |args| {
        // access to foo, bar and baz


~18K SLoC