let_clone/
lib.rs

1/// # Examples
2///
3/// ```
4/// tokio::spawn({
5///     let_clone!(self: this, cx.{io, disk, health_check: check});
6///     async move {
7///         this.do_something(io, disk, check)
8///     }
9/// })
10/// ```
11#[macro_export]
12macro_rules! let_clone {
13  ($self:ident . { $($cloneable:ident $(: $rename:ident)?),+$(,)? }, $($tail:tt)+) => {
14    $crate::let_clone!($($self.$cloneable $(: $rename)?),+);
15    $crate::let_clone!($($tail)+);
16  };
17  ($self:ident . { $($cloneable:ident $(: $rename:ident)?),+$(,)? }) => {
18    $crate::let_clone!($($self.$cloneable $(: $rename)?),+);
19  };
20
21  ($($cloneable:ident).+ $(: $rename:ident)?, $($tail:tt)+) => {
22    $crate::let_clone!(@inner $($cloneable).+;;$($rename)?);
23    $crate::let_clone!($($tail)+);
24  };
25  ($($cloneable:ident).+ $(: $rename:ident)? $(,)?) => {
26    $crate::let_clone!(@inner $($cloneable).+;;$($rename)?);
27  };
28
29  (@inner $root:ident$(.$nested:ident)+; $($tail:ident).*; $($rename:ident)?) => {
30    $crate::let_clone!(@inner $($nested).+; $($tail.)*$root; $($rename)?);
31  };
32  (@inner $cloneable:ident; $($nested:ident).*; $rename:ident) => {
33    let $rename = $($nested.)*$cloneable.clone();
34  };
35  (@inner $cloneable:ident; $($nested:ident).*; ) => {
36    let $cloneable = $($nested.)*$cloneable.clone();
37  };
38}
39
40#[cfg(test)]
41mod tests {
42    use super::*;
43
44    #[test]
45    fn it_works() {
46        #[derive(Clone)]
47        struct Foo;
48        struct Bar {
49            baz: String,
50            boo: String,
51        }
52        impl Foo {
53            fn foobar(self, _baz: String) {}
54
55            fn run(&self, bar: &Bar) {
56                std::thread::spawn({
57                    let_clone!(self: this, bar.baz, bar.{baz: baz2, boo}, bar.boo: boo2);
58                    let _ = (baz2, boo, boo2);
59                    move || this.foobar(baz)
60                });
61            }
62        }
63        Foo.run(&Bar {
64            baz: "baz".into(),
65            boo: "boo".into(),
66        });
67    }
68}