|  | /// Define a trait as usual, and a macro that can be used to instantiate | 
|  | /// implementations of it. | 
|  | /// | 
|  | /// There *must* be section markers in the trait definition: | 
|  | /// @section type for associated types | 
|  | /// @section self for methods | 
|  | /// @section nodelegate for arbitrary tail that is not forwarded. | 
|  | macro_rules! trait_template { | 
|  | ($(#[$doc:meta])* pub trait $name:ident $($methods:tt)*) => { | 
|  | macro_rules! $name { | 
|  | ($m:ident $extra:tt) => { | 
|  | $m! { | 
|  | $extra | 
|  | pub trait $name $($methods)* | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | remove_sections! { [] | 
|  | $(#[$doc])* | 
|  | pub trait $name $($methods)* | 
|  |  | 
|  | // This is where the trait definition is reproduced by the macro. | 
|  | // It makes the source links point to this place! | 
|  | // | 
|  | // I'm sorry, you'll have to find the source by looking at the | 
|  | // source of the module the trait is defined in. | 
|  | // | 
|  | // We use this nifty macro so that we can automatically generate | 
|  | // delegation trait impls and implement the graph traits for more | 
|  | // types and combinators. | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | macro_rules! remove_sections_inner { | 
|  | ([$($stack:tt)*]) => { | 
|  | $($stack)* | 
|  | }; | 
|  | // escape the following tt | 
|  | ([$($stack:tt)*] @escape $_x:tt $($t:tt)*) => { | 
|  | remove_sections_inner!([$($stack)*] $($t)*); | 
|  | }; | 
|  | ([$($stack:tt)*] @section $x:ident $($t:tt)*) => { | 
|  | remove_sections_inner!([$($stack)*] $($t)*); | 
|  | }; | 
|  | ([$($stack:tt)*] $t:tt $($tail:tt)*) => { | 
|  | remove_sections_inner!([$($stack)* $t] $($tail)*); | 
|  | }; | 
|  | } | 
|  |  | 
|  | // This is the outer layer, just find the { } of the actual trait definition | 
|  | // recurse once into { }, but not more. | 
|  | macro_rules! remove_sections { | 
|  | ([$($stack:tt)*]) => { | 
|  | $($stack)* | 
|  | }; | 
|  | ([$($stack:tt)*] { $($tail:tt)* }) => { | 
|  | $($stack)* { | 
|  | remove_sections_inner!([] $($tail)*); | 
|  | } | 
|  | }; | 
|  | ([$($stack:tt)*] $t:tt $($tail:tt)*) => { | 
|  | remove_sections!([$($stack)* $t] $($tail)*); | 
|  | }; | 
|  | } | 
|  |  | 
|  | macro_rules! deref { | 
|  | ($e:expr) => { | 
|  | *$e | 
|  | }; | 
|  | } | 
|  | macro_rules! deref_twice { | 
|  | ($e:expr) => { | 
|  | **$e | 
|  | }; | 
|  | } | 
|  |  | 
|  | /// Implement a trait by delegation. By default as if we are delegating | 
|  | /// from &G to G. | 
|  | macro_rules! delegate_impl { | 
|  | ([] $($rest:tt)*) => { | 
|  | delegate_impl! { [['a, G], G, &'a G, deref] $($rest)* } | 
|  | }; | 
|  | ([[$($param:tt)*], $self_type:ident, $self_wrap:ty, $self_map:ident] | 
|  | pub trait $name:ident $(: $sup:ident)* $(+ $more_sup:ident)* { | 
|  |  | 
|  | // "Escaped" associated types. Stripped before making the `trait` | 
|  | // itself, but forwarded when delegating impls. | 
|  | $( | 
|  | @escape [type $assoc_name_ext:ident] | 
|  | // Associated types. Forwarded. | 
|  | )* | 
|  | $( | 
|  | @section type | 
|  | $( | 
|  | $(#[$_assoc_attr:meta])* | 
|  | type $assoc_name:ident $(: $assoc_bound:ty)*; | 
|  | )+ | 
|  | )* | 
|  | // Methods. Forwarded. Using $self_map!(self) around the self argument. | 
|  | // Methods must use receiver `self` or explicit type like `self: &Self` | 
|  | // &self and &mut self are _not_ supported. | 
|  | $( | 
|  | @section self | 
|  | $( | 
|  | $(#[$_method_attr:meta])* | 
|  | fn $method_name:ident(self $(: $self_selftype:ty)* $(,$marg:ident : $marg_ty:ty)*) $(-> $mret:ty)?; | 
|  | )+ | 
|  | )* | 
|  | // Arbitrary tail that is ignored when forwarding. | 
|  | $( | 
|  | @section nodelegate | 
|  | $($tail:tt)* | 
|  | )* | 
|  | }) => { | 
|  | impl<$($param)*> $name for $self_wrap where $self_type: $name { | 
|  | $( | 
|  | $( | 
|  | type $assoc_name = $self_type::$assoc_name; | 
|  | )* | 
|  | )* | 
|  | $( | 
|  | type $assoc_name_ext = $self_type::$assoc_name_ext; | 
|  | )* | 
|  | $( | 
|  | $( | 
|  | fn $method_name(self $(: $self_selftype)* $(,$marg: $marg_ty)*) $(-> $mret)? { | 
|  | $self_map!(self).$method_name($($marg),*) | 
|  | } | 
|  | )* | 
|  | )* | 
|  | } | 
|  | } | 
|  | } |