#![recursion_limit = "256"]
use tt_call::{parse_type, tt_call, tt_return};
macro_rules! comma_separated {
{
$caller:tt
parser = [{ $parser:ident }]
input = [{ $($input:tt)* }]
} => {
tt_call! {
macro = [{ $parser }]
input = [{ $($input)* }]
~~> private_comma_separated! {
$caller
parser = [{ $parser }]
elements = [{ }]
}
}
};
}
#[doc(hidden)]
macro_rules! private_comma_separated {
{
$caller:tt
parser = [{ $parser:ident }]
elements = [{ $($elements:tt)* }]
$name:ident = [{ $($current:tt)* }]
rest = [{ }]
} => {
tt_return! {
$caller
$($elements)*
element = [{ $($current)* }]
}
};
{
$caller:tt
parser = [{ $parser:ident }]
elements = [{ $($elements:tt)* }]
$name:ident = [{ $($current:tt)* }]
rest = [{ , }]
} => {
tt_return! {
$caller
$($elements)*
element = [{ $($current)* }]
}
};
{
$caller:tt
parser = [{ $parser:ident }]
elements = [{ $($elements:tt)* }]
$name:ident = [{ $($current:tt)* }]
rest = [{ , $($rest:tt)+ }]
} => {
tt_call! {
macro = [{ $parser }]
input = [{ $($rest)* }]
~~> private_comma_separated! {
$caller
parser = [{ $parser }]
elements = [{
$($elements)*
element = [{ $($current)* }]
}]
}
}
};
}
macro_rules! mangle_type_names {
($($input:tt)*) => {
tt_call! {
macro = [{ comma_separated }]
parser = [{ parse_type }]
input = [{ $($input)* }]
~~> private_mangle_type_names
}
};
}
#[doc(hidden)]
macro_rules! private_mangle_type_names {
{
$(
element = [{ $($element:tt)* }]
)*
} => {
&[
$(
concat!(
$(
mangle_token!($element),
)*
),
)*
]
};
}
#[doc(hidden)]
macro_rules! mangle_token {
($ident:ident) => {
concat!("_", stringify!($ident))
};
(&) => {
"_ref"
};
(->) => {
"_to"
};
(($($parenthesized:tt)*)) => {
concat!(
$(
mangle_token!($parenthesized),
)*
)
};
($other:tt) => {
""
};
}
fn main() {
static MANGLED: &[&str] = mangle_type_names! {
std::fs::File,
&'a mut str,
impl Display,
fn(s: &str) -> String,
};
assert_eq!(
MANGLED,
[
"_std_fs_File",
"_ref_mut_str",
"_impl_Display",
"_fn_s_ref_str_to_String",
]
);
println!("{:#?}", MANGLED);
}