macro_rules! subst_rules {
($e:expr => =>) => ($e.into_owned());
($e:expr => => [$($pre:tt)*] $from:tt [$($post:tt)*] => $to:expr; $($t:tt)*) =>
(subst_rules!(subst(&$e,
&[$($pre.into_pre_cond()),*], $from, &[$($post.into_post_cond()),*],
$to.into_transform(),
concat!("[", stringify!($($pre)*), "] ", stringify!($from),
" [", stringify!($($post)*), "] => ", stringify!($to)))
=> => $($t)*));
($e:expr => => [$($pre:tt)*] $from:tt => $to:expr; $($t:tt)*) =>
(subst_rules!(subst(&$e,
&[$($pre.into_pre_cond()),*], $from, &[],
$to.into_transform(),
concat!("[", stringify!($($pre)*), "] ", stringify!($from),
" => ", stringify!($to)))
=> => $($t)*));
($e:expr => => $from:tt [$($post:tt)*] => $to:expr; $($t:tt)*) =>
(subst_rules!(subst(&$e,
&[], $from, &[$($post.into_post_cond()),*],
$to.into_transform(),
concat!(stringify!($from), " [", stringify!($($post)*), "] => ",
stringify!($to)))
=> => $($t)*));
($e:expr => => $from:tt => $to:expr; $($t:tt)*) =>
(subst_rules!(subst(&$e,
&[], $from, &[],
$to.into_transform(),
concat!(stringify!($from), " => ", stringify!($to)))
=> => $($t)*));
($e:expr => $($t:tt)*) => ({
use std::borrow::Cow;
use $crate::{Search, Transform, IntoTransform, Cond, IntoCond};
#[inline(always)]
fn subst<'a, From: Search>(s: &'a str, preconds: &[Cond], from: From, postconds: &[Cond],
to: Transform, rulestring: &str) -> Cow<'a, str> {
let ret = $crate::subst(s, preconds, from, postconds, to);
if s != ret { debug!("{} --> {} ({})", s, ret, rulestring); }
ret
}
subst_rules!($e => => $($t)*)
});
}