#[doc(hidden)]
#[macro_export]
macro_rules! utils_escape {
([($($G:tt)*) $($T:tt)*] $R:tt $E:tt $N:tt) => {
$crate::utils::escape!([$($G)*] [] $E ($crate::utils_escape_collect_parens; [$($T)*] $R $E ($crate::utils::escape) $N));
};
([[$($G:tt)*] $($T:tt)*] $R:tt $E:tt $N:tt) => {
$crate::utils::escape!([$($G)*] [] $E ($crate::utils_escape_collect_brackets; [$($T)*] $R $E ($crate::utils::escape) $N));
};
([{$($G:tt)*} $($T:tt)*] $R:tt $E:tt $N:tt) => {
$crate::utils::escape!([$($G)*] [] $E ($crate::utils_escape_collect_braces; [$($T)*] $R $E ($crate::utils::escape) $N));
};
([$H:tt $($T:tt)*] $R:tt $E:tt $N:tt) => {
$crate::utils_escape_detect!([=$H=] [$($T)*] $R $E $N);
};
([] [$($R:tt)*] $E:tt ($F:path; $($C:tt)*)) => {
$F!([$($R)*] $($C)*);
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! utils_escape_detect {
([$(=)$+] $T:tt [$($R:tt)*] [$($E:tt)*] $N:tt) => {
$crate::utils::escape!($T [$($R)* $($E)*] [$($E)*] $N);
};
([=$H:tt=] $T:tt [$($R:tt)*] $E:tt $N:tt) => {
$crate::utils::escape!($T [$($R)* $H] $E $N);
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! utils_escape_collect_parens {
([$($G:tt)*] $T:tt [$($R:tt)*] $E:tt ($F:path) $N:tt) => {
$F!($T [$($R)* ($($G)*)] $E $N);
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! utils_escape_collect_brackets {
([$($G:tt)*] $T:tt [$($R:tt)*] $E:tt ($F:path) $N:tt) => {
$F!($T [$($R)* [$($G)*]] $E $N);
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! utils_escape_collect_braces {
([$($G:tt)*] $T:tt [$($R:tt)*] $E:tt ($F:path) $N:tt) => {
$F!($T [$($R)* {$($G)*}] $E $N);
};
}
#[doc(inline)]
pub use utils_escape as escape;
#[doc(hidden)]
#[macro_export]
macro_rules! utils_escape_repetitions {
([($($G:tt)*) $($T:tt)*] $R:tt $E:tt $N:tt) => {
$crate::utils::escape_repetitions!([$($G)*] [] $E ($crate::utils_escape_collect_parens; [$($T)*] $R $E ($crate::utils::escape_repetitions) $N));
};
([[$($G:tt)*] $($T:tt)*] $R:tt $E:tt $N:tt) => {
$crate::utils::escape_repetitions!([$($G)*] [] $E ($crate::utils_escape_collect_brackets; [$($T)*] $R $E ($crate::utils::escape_repetitions) $N));
};
([{$($G:tt)*} $($T:tt)*] $R:tt $E:tt $N:tt) => {
$crate::utils::escape_repetitions!([$($G)*] [] $E ($crate::utils_escape_collect_braces; [$($T)*] $R $E ($crate::utils::escape_repetitions) $N));
};
([$H:tt ($($G:tt)*) $($T:tt)*] $R:tt $E:tt $N:tt) => {
$crate::utils_escape_repetitions_detect!([=$H=] ($($G)*) [$($T)*] $R $E $N);
};
([$H:tt $($T:tt)*] [$($R:tt)*] $E:tt $N:tt) => {
$crate::utils::escape_repetitions!([$($T)*] [$($R)* $H] $E $N);
};
([] [$($R:tt)*] $E:tt ($F:path; $($C:tt)*)) => {
$F!([$($R)*] $($C)*);
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! utils_escape_repetitions_detect {
([$(=)$+] ($($G:tt)*) $T:tt [$($R:tt)*] [$($E:tt)*] $N:tt) => {
$crate::utils::escape_repetitions!([$($G)*] [] [$($E)*] ($crate::utils_escape_collect_parens; $T [$($R)* $($E)*] [$($E)*] ($crate::utils::escape_repetitions) $N));
};
([=$H:tt=] ($($G:tt)*) $T:tt [$($R:tt)*] $E:tt $N:tt) => {
$crate::utils::escape_repetitions!([$($G)*] [] $E ($crate::utils_escape_collect_parens; $T [$($R)* $H] $E ($crate::utils::escape_repetitions) $N));
};
}
#[doc(inline)]
pub use utils_escape_repetitions as escape_repetitions;
#[doc(hidden)]
#[macro_export]
macro_rules! utils_select {
([$($T:tt)*] [$([[$($R1:tt)*] [$($R2:tt)*]])+] $N:tt $D:tt) => {
macro_rules! __rukt_dispatch {
$(
([$($R1)*] ($FF:path; $D($CC:tt)*)) => {
$FF!([$($R2)*] $D($CC)*);
};
)*
}
__rukt_dispatch!([$($T)*] $N);
};
}
#[doc(inline)]
pub use utils_select as select;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_escape_repetitions() {
macro_rules! check {
($T:tt $expected:expr) => {
assert_eq!(stringify!($T), $expected);
};
}
escape_repetitions!([] [] [$REP] (check; "[]"));
escape_repetitions!([hello world] [] [$REP] (check; "[hello world]"));
escape_repetitions!([hello(world)] [] [$REP] (check; "[hello(world)]"));
escape_repetitions!([{ hello }(world)] [] [$REP] (check; "[{ hello }(world)]"));
escape_repetitions!([$($hello)* world] [] [$REP] (check; "[$REP($hello)* world]"));
escape_repetitions!([$($hello)*(world)] [] [$REP] (check; "[$REP($hello)*(world)]"));
escape_repetitions!([{ $($hello)* }(world)] [] [$REP] (check; "[{ $REP($hello)* }(world)]"));
escape_repetitions!([$($hello)* $($world:tt, 42)+] [] [$REP] (check; "[$REP($hello)* $REP($world:tt, 42)+]"));
escape_repetitions!([$($hello)*($($world:tt, 42)+)] [] [$REP] (check; "[$REP($hello)*($REP($world:tt, 42)+)]"));
escape_repetitions!([{ $($hello)* }($($world:tt, 42)+)] [] [$REP] (check; "[{ $REP($hello)* }($REP($world:tt, 42)+)]"));
escape_repetitions!([$($hello $(;)?)* $($world:tt, 42)+] [] [$REP] (check; "[$REP($hello $REP(;)?)* $REP($world:tt, 42)+]"));
escape_repetitions!([$($hello $(;)?)*($($world:tt, 42)+)] [] [$REP] (check; "[$REP($hello $REP(;)?)*($REP($world:tt, 42)+)]"));
escape_repetitions!([{ $($hello $(;)?)* }($($world:tt, 42)+)] [] [$REP] (check; "[{ $REP($hello $REP(;)?)* }($REP($world:tt, 42)+)]"));
}
}