1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/// Clones all the given variables into new variables. Intended for use with `move` closures.
///
/// # Examples
///
/// Compare this:
///
/// ```rust
/// # use std::sync::Arc;
/// # use std::sync::Mutex;
/// # use std::thread;
/// # use std::collections::HashSet;
/// 
/// # fn main() {
/// let i = Arc::new(Mutex::new(String::from("hello world")));
/// let o = Arc::new(Mutex::new(String::new()));
/// for _ in "hello world".chars() {
///     thread::spawn({let i = i.clone(); let o = o.clone(); move || {
///         let c = i.lock().unwrap().pop();
///         let c = c.unwrap();
///         o.lock().unwrap().push(c);
///     }}).join();
/// }
/// # assert_eq!("dlrow olleh", &o.lock().unwrap().clone());
/// # }
/// ```
///
/// To this:
///
/// ```rust
/// #[macro_use]
/// extern crate clone_all;
/// # use std::sync::Arc;
/// # use std::sync::Mutex;
/// # use std::thread;
/// # use std::collections::HashSet;
/// 
/// # fn main() {
/// let i = Arc::new(Mutex::new(String::from("hello world")));
/// let o = Arc::new(Mutex::new(String::new()));
/// for _ in "hello world".chars() {
///     thread::spawn({clone_all!(i, o); move || {
///         let c = i.lock().unwrap().pop();
///         let c = c.unwrap();
///         o.lock().unwrap().push(c);
///     }}).join();
/// }
/// # assert_eq!("dlrow olleh", &o.lock().unwrap().clone());
/// # }
/// ```
#[macro_export]
macro_rules! clone_all {
    ($($i:ident),+) => {
        $(let $i = $i.clone();)+
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn test_clone_string() {
        let s: String = "hello world".into();
        {
            clone_all!(s);
            ::std::mem::drop(s);
        }
        ::std::mem::drop(s);
    }

    #[test]
    fn test_clone_multiple_strings() {
        let s1: String = "hello world".into();
        let s2: String = "goodbye".into();
        {
            clone_all!(s1, s2);
            ::std::mem::drop(s1);
            ::std::mem::drop(s2);
        }
        ::std::mem::drop(s1);
        ::std::mem::drop(s2);
    }
}