#[macro_export] macro_rules! function_group {
(@Visibilty ($vis:tt fn $($tail:tt)*) -> (($($trait:tt)*), ($($func:tt)*))) => {
function_group!(@Name (fn $($tail)*) -> (($($trait)* $vis), ($($func)* $vis)));
};
(@Visibilty (fn $($tail:tt)*) -> (($($trait:tt)*), ($($func:tt)*))) => {
function_group!(@Name (fn $($tail)*) -> (($($trait)*), ($($func)*)));
};
(@Name (fn $name:ident $($tail:tt)*) -> (($($trait:tt)*), ($($func:tt)*))) => {
function_group!(@ReturnType ($name $($tail)*) -> (($($trait)* trait $name), ($($func)* fn $name<T : $name>)));
};
(@ReturnType ($name:ident -> $ret:ty {$($tail:tt)*}) -> (($($trait:tt)*), ($($func:tt)*))) => {
function_group!(@Define ($name, $ret, {$($tail)*}) -> (($($trait)*), ($($func)*)));
};
(@ReturnType ($name:ident {$($tail:tt)*}) -> (($($trait:tt)*), ($($func:tt)*))) => {
function_group!(@Define ($name, (), {$($tail)*}) -> (($($trait)*), ($($func)*)));
};
(@Define ($name:ident, $ret:ty, {$($tail:tt)*}) -> (($($trait:tt)*), ($($func:tt)*))) => {
$($trait)*{
fn $name(self) -> $ret;
}
$($func)*(a : T) -> $ret {
a.$name()
}
function_group!(@Implementations ($name, $ret, $($tail)*));
};
(@Implementations ($name:ident, $ret:ty, $(($( $($var:ident)* : $type:ty),*) {$code:expr} $(;)*)*)) => {
$(impl $name for ($($type,)*){
fn $name(self) -> $ret {
let ($($($var)*,)*) = self;
$code
}
})*
};
(@Implementations ($($tail:tt)*)) => {
$($tail)*
};
($($tail:tt)*) => {
function_group!(@Visibilty ($($tail)*) -> ((), ()));
};
}