Macro generics::parse

source ·
macro_rules! parse {
    (
        $callback:path { $($callback_args:tt)* } < $($token:tt)*
    ) => { ... };
    (
        $callback:path { $($callback_args:tt)* } $($token:tt)*
    ) => { ... };
}
Expand description

Parses (optional) generics and (optional) subsequent where clause.

This macro accepts an input in the following form:

$callback:path { $($callback_args:tt)* }
$(
    <$generics>
    $($tokens_between_generics_and_where_clause:tt)*
    $(where $where_clause)?
)?
$(
    $( ; | { $($body:tt)* } )
    $($remaining_tokens:tt)*
)?

and expands into

$callback! {
    $($callback_args)*
    [ $(<$generics>)? ]
    [ $(<$generics_without_constraints>)? ]
    [ $($(where $where_clause)?)? ]
    $($($tokens_between_generics_and_where_clause)*)?
    $(
        $( ; | { $($body)* } )
        $($remaining_tokens)*
    )?
}

§Examples

pub trait TheTrait { }

#[doc(hidden)]
pub use generics::parse as generics_parse;
#[doc(hidden)]
pub use std::compile_error as std_compile_error;

#[macro_export]
macro_rules! impl_the_trait {
    (
        $name:ident $($token:tt)*
    ) => {
        $crate::generics_parse! {
            $crate::impl_the_trait_impl {
                @impl $name
            }
            $($token)*
        }
    };
}

#[doc(hidden)]
#[macro_export]
macro_rules! unexpected_token {
    () => { };
}

#[doc(hidden)]
#[macro_export]
macro_rules! impl_the_trait_impl {
    (
        @impl $name:ident [$($g:tt)*] [$($r:tt)*] [$($w:tt)*]
    ) => {
        impl $($g)* $crate::TheTrait for $name $($r)* $($w)* { }
    };
    (
        @impl $name:ident [$($g:tt)*] [$($r:tt)*] [$($w:tt)*] $token:tt $($tail:tt)* 
    ) => {
        $crate::unexpected_token!($token);
        $crate::std_compile_error!(
            "invalid input, allowed input is '$name:ident $(<$generics> $(where $where_clause)?)?'"
        );
    };
}