#[macro_export]
macro_rules! clone{
($(,)?) => {};
($scope:ident . $name:ident $(, $($tail:tt)*)?) => {
let $name = $scope . $name.clone();
$($crate::clone!($($tail)*);)?
};
(mut $scope:ident . $name:ident $(, $($tail:tt)*)?) => {
let mut $name = $scope . $name.clone();
$($crate::clone!($($tail)*);)?
};
($name:ident $(, $($tail:tt)*)?) => {
let $name = $name.clone();
$($crate::clone!($($tail)*);)?
};
(mut $name:ident $(, $($tail:tt)*)?) => {
let mut $name = $name.clone();
$($crate::clone!($($tail)*);)?
};
}
#[cfg(test)]
mod tests {
use std::mem;
#[derive(Clone)]
struct Test;
impl Drop for Test {
fn drop(&mut self) {}
}
impl Test {
fn mutate(&mut self) {}
}
struct Scope {
y: Test,
}
impl Scope {
fn clone_member(&self) {
clone!(self.y);
mem::drop(y);
}
}
#[test]
fn basic() {
let x = Test;
{
clone!(x);
mem::drop(x);
}
mem::drop(x);
}
#[test]
fn mutate() {
let x = Test;
{
clone!(mut x);
x.mutate();
}
}
#[test]
fn multi() {
let x = Test;
let y = Test;
{
clone!(x, mut y);
y.mutate();
mem::drop(x);
mem::drop(y);
}
mem::drop(x);
mem::drop(y);
}
#[test]
fn scope() {
let x = Scope { y: Test };
{
clone!(x.y);
mem::drop(y);
}
mem::drop(x);
}
#[test]
fn mutable_scope() {
let x = Scope { y: Test };
x.clone_member();
{
clone!(mut x.y);
y.mutate();
mem::drop(y);
}
mem::drop(x);
}
}