shadow_clone/lib.rs
1#![no_std]
2//! Go the the [readme](https://crates.io/crates/shadow-clone) file for more documentation.
3
4/// Use this macro to clone variables into the current scope shadowing old ones.
5///
6/// # Examples
7/// ```rust,compile_fail
8/// let s = "foo".to_string();
9/// let c = move |x: i32| format!("{}{}", s, x);
10/// let bar = s;
11/// ```
12/// This will not compile as `s` has been moved into the closure.
13///
14/// This issue can be solved with this macro.
15/// ```rust
16/// use shadow_clone::shadow_clone;
17/// let s = "foo".to_string();
18/// {
19///     shadow_clone!(s);
20///     let c = move |x: i32| format!("{}{}", s, x);
21/// }
22/// let bar = s;
23/// ```
24/// That expands to,
25/// ```rust
26/// use shadow_clone::shadow_clone;
27/// let s = "foo".to_string();
28/// {
29///     let s = s.clone();
30///     let c = move |x: i32| format!("{}{}", s, x);
31/// }
32/// let bar = s;
33/// ```
34/// You can also clone multiple variables separated by commas. `shadow_clone!(foo, bar);`
35///
36/// You can also bind a clone as mutable by prefixing with `mut`. `shadow_clone!(mut foo);`
37#[macro_export]
38macro_rules! shadow_clone {
39    { $to_clone:ident, $($tt:tt)* } => {
40        $crate::shadow_clone!($to_clone);
41        $crate::shadow_clone!($($tt)*)
42    };
43    { mut $to_clone:ident, $($tt:tt)* } => {
44        $crate::shadow_clone!(mut $to_clone);
45        $crate::shadow_clone!($($tt)*)
46    };
47    { (mut) $to_clone:ident, $($tt:tt)* } => {
48        $crate::shadow_clone!(mut $to_clone);
49        $crate::shadow_clone!($($tt)*)
50    };
51    { $to_clone:ident } => {
52        let $to_clone = $to_clone.clone();
53    };
54    { mut $to_clone:ident } => {
55        let mut $to_clone = $to_clone.clone();
56    };
57    { (mut) $to_clone:ident } => {
58        $crate::shadow_clone!(mut $to_clone)
59    };
60    () => ()
61}