2 /// Define a trait as usual, and a macro that can be used to instantiate
3 /// implementations of it.
5 /// There *must* be section markers in the trait defition:
6 /// @section type for associated types
7 /// @section self for methods
8 /// @section nodelegate for arbitrary tail that is not forwarded.
9 macro_rules
! trait_template
{
10 ($
(#[$doc:meta])* pub trait $name:ident $($methods:tt)*) => {
12 ($m
:ident $extra
:tt
) => {
15 pub trait $name $
($methods
)*
22 pub trait $name $
($methods
)*
24 // This is where the trait definition is reproduced by the macro.
25 // It makes the source links point to this place!
27 // I'm sorry, you'll have to find the source by looking at the
28 // source of the module the trait is defined in.
30 // We use this nifty macro so that we can automatically generate
31 // delegation trait impls and implement the graph traits for more
32 // types and combinators.
37 macro_rules
! remove_sections_inner
{
38 ([$
($stack
:tt
)*]) => {
41 // escape the following tt
42 ([$
($stack
:tt
)*] @escape $_x
:tt $
($t
:tt
)*) => {
43 remove_sections_inner
!([$
($stack
)*] $
($t
)*);
45 ([$
($stack
:tt
)*] @section $x
:ident $
($t
:tt
)*) => {
46 remove_sections_inner
!([$
($stack
)*] $
($t
)*);
48 ([$
($stack
:tt
)*] $t
:tt $
($tail
:tt
)*) => {
49 remove_sections_inner
!([$
($stack
)* $t
] $
($tail
)*);
53 // This is the outer layer, just find the { } of the actual trait definition
54 // recurse once into { }, but not more.
55 macro_rules
! remove_sections
{
56 ([$
($stack
:tt
)*]) => {
59 ([$
($stack
:tt
)*] { $($tail:tt)* }
) => {
61 remove_sections_inner
!([] $
($tail
)*);
64 ([$
($stack
:tt
)*] $t
:tt $
($tail
:tt
)*) => {
65 remove_sections
!([$
($stack
)* $t
] $
($tail
)*);
72 macro_rules
! deref_twice
{
76 /// Implement a trait by delegation. By default as if we are delegating
78 macro_rules
! delegate_impl
{
79 ([] $
($rest
:tt
)*) => {
80 delegate_impl
! { [['a, G], G, &'a G, deref] $($rest)* }
82 ([[$
($param
:tt
)*], $self_type
:ident
, $self_wrap
:ty
, $self_map
:ident
]
83 pub trait $name
:ident $
(: $sup
:ident
)* $
(+ $more_sup
:ident
)* {
85 // "Escaped" associated types. Stripped before making the `trait`
86 // itself, but forwarded when delegating impls.
88 @escape
[type $assoc_name_ext
:ident
]
89 // Associated types. Forwarded.
94 $
(#[$_assoc_attr:meta])*
95 type $assoc_name
:ident $
(: $assoc_bound
:ty
)*;
98 // Methods. Forwarded. Using $self_map!(self) around the self argument.
99 // Methods must use receiver `self` or explicit type like `self: &Self`
100 // &self and &mut self are _not_ supported.
104 $
(#[$_method_attr:meta])*
105 fn $method_name
:ident(self $
(: $self_selftype
:ty
)* $
(,$marg
:ident
: $marg_ty
:ty
)*) -> $mret
:ty
;
108 // Arbitrary tail that is ignored when forwarding.
114 impl<$
($param
)*> $name
for $self_wrap
where $self_type
: $name
{
117 type $assoc_name
= $self_type
::$assoc_name
;
121 type $assoc_name_ext
= $self_type
::$assoc_name_ext
;
125 fn $
method_name(self $
(: $self_selftype
)* $
(,$marg
: $marg_ty
)*) -> $mret
{
126 $self_map
!(self).$
method_name($
($marg
),*)