#[macro_export]
macro_rules! update {
{$($t:tt)*} => {
$crate::find_expr! { {} $($t)* }
};
{$e:expr, $($t:tt)*} => {{
let mut temp = $e;
$crate::update_inner! {
@main temp, $($t)*
}
temp
}};
}
#[doc(hidden)]
#[macro_export]
macro_rules! find_expr {
{{$($update:tt)*} ..$e:expr} => {{
let mut temp = $e;
$crate::update_inner! {
@main temp, { $($update)* }
}
temp
}};
{{$($update:tt)*} $next:tt $($t:tt)*} => {
$crate::find_expr! {
{$($update)* $next} $($t)*
}
};
{{$($update:tt)*}} => {
compile_error!(concat!("Expected `..<expr>` at the end or `<expr>,` at the beginning. Got: \n\n", stringify!($($update)*), "\n\n"))
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! update_inner {
(@main $e:expr, { $($t:tt)* }) => {
$crate::update_inner! {
@helper {$e} {} {} $($t)*
}
};
(@main $e:expr, $value:expr $(,)?) => {
$e = $value;
};
(@helper {$e:expr} {$($parsed_name:ident {$($parsed_inner:tt)*})*} {$($current:tt)*} $name:ident:) => {
$(
$crate::update_inner! { @main $e.$parsed_name, $($parsed_inner)* }
)*
$crate::update_inner! { @main $e.$name, $($current)* }
};
(@helper {$e:expr} {$($parsed_name:ident {$($parsed_inner:tt)*})*} {$($current:tt)*} $name:ident: , $other:ident $($rest:tt)*) => {
$crate::update_inner! {
@helper {$e} {$($parsed_name {$($parsed_inner)*})* $name {$($current)*}} {} $other $($rest)*
}
};
(@helper {$e:expr} {$($parsed_name:ident {$($parsed_inner:tt)*})*} {$($current:tt)*} $name:ident: $t:tt $($rest:tt)*) => {
$crate::update_inner! {
@helper {$e} {$($parsed_name {$($parsed_inner)*})* } {$($current)* $t} $name: $($rest)*
}
};
}