1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#[ macro_export ]
macro_rules! struct_parser_display {
	( $($rest:tt)* ) => {
		struct_parser! { $($rest)* }
		struct_display! { $($rest)* }
	};
}

#[ macro_export ]
macro_rules! struct_parser {

	( < $($rest:tt)* ) => {
		struct_parser! (@outer 'inp [] < $($rest)*);
	};

	( $first:ident $($rest:tt)* ) => {
		struct_parser! (@outer 'inp [] $first $($rest)*);
	};

	(
		@outer $inp_life_old:tt [$($param_decl:tt)*]
		input_lifetime = $inp_life:tt;
		$($rest:tt)*
	) => {
		struct_parser! (@outer $inp_life [$($param_decl)*] $($rest)*);
	};
		
	(
		@outer $inp_life:tt [$($param_decl_old:tt)*]
		params = { $($param_decl:tt)* }
		$($rest:tt)*
	) => {
		struct_parser! (@outer $inp_life [$($param_decl)*] $($rest)*);
	};
		
	(
		@outer $inp_life:tt [$($param_decl:tt)*]
		$( #[ $($attr:tt)* ] )*
		$name:ident
		$( < $($param:tt),* > )?
		{ $($fields:tt)* }
		= [ $($args:tt)* ]
	) => {
		struct_parser! (
			@main $( #[ $($attr)* ] )* $name $inp_life
			[ $($param_decl)* ]
			[ $( $($param),* )? ]
			[ { $($fields)* } ]
			[ $($args)* ]);
	};

	(
		@outer $inp_life:tt [$($param_decl:tt)*]
		$name:ident
		$( < $($param:tt),* > )?
		( $($fields:tt)* )
		= [ $($args:tt)* ]
	) => {
		struct_parser! (
			@main $name $inp_life
			[ $( $($param_decl)* )? ]
			[ $($param),* ]
			[ ( $($fields)* ) ]
			[ $($args)* ]);
	};

	(
		@main $( #[ $($attr:tt)* ] )* $name:ident $inp_life:tt
		[ $($param_decl:tt)* ]
		[ $($param:tt)* ]
		[ $($fields:tt)* ]
		[ $($args:tt)* ]
	) => {
		$( #[ $($attr)* ] )*
		impl <$inp_life, $($param_decl)*> FromParser <$inp_life> for $name <$($param)*> {
			#[ inline ]
			fn from_parser (parser: & mut Parser <$inp_life>) -> ParseResult <Self> {
				parse! (parser, $($args)*);
				Ok (Self $($fields)*)
			}
		}
	};

}

#[ macro_export ]
macro_rules! struct_display {

	( < $($rest:tt)* ) => {
		struct_display! (@outer 'inp [] < $($rest)*);
	};

	( $first:ident $($rest:tt)* ) => {
		struct_display! (@outer 'inp [] $first $($rest)*);
	};

	(
		@outer $inp_life_old:tt [$($param_decl:tt)*]
		input_lifetime = $inp_life:tt;
		$($rest:tt)*
	) => {
		struct_display! (@outer $inp_life [$($param_decl)*] $($rest)*);
	};

	(
		@outer $inp_life:tt [$($param_decl_old:tt)*]
		params = { $($param_decl:tt)* }
		$($rest:tt)*
	) => {
		struct_display! (@outer $inp_life [$($param_decl)*] $($rest)*);
	};

	(
		@outer $inp_life:tt [$($param_decl:tt)*]
		$name:ident
		$( < $($param:tt),* > )?
		{ $($fields:tt)* }
		= [ $($args:tt)* ]
	) => {
		struct_display! (
			@main $name $inp_life
			[ $($param_decl)* ]
			[ $( $($param),* )? ]
			[ { $($fields)* } ]
			[ $($args)* ]);
	};

	(
		@outer $inp_life:tt [$($param_decl:tt)*]
		$name:ident
		$( < $($param:tt),* > )?
		( $($fields:tt)* )
		= [ $($args:tt)* ]
	) => {
		struct_display! (
			@main $name $inp_life
			[ $($param_decl)* ]
			[ $( $($param),* )? ]
			[ ( $($fields)* ) ]
			[ $($args)* ]);
	};

	(
		@main $name:ident $inp_life:tt
		[ $($param_decl:tt)* ]
		[ $($param:tt),* ]
		[ $($fields:tt)* ]
		[ $($args:tt)* ]
	) => {
		impl <$inp_life, $($param_decl)*> ::std::fmt::Display
				for $name <$($param),*> {
			fn fmt (& self, formatter: & mut ::std::fmt::Formatter) -> ::std::fmt::Result {
				let Self $($fields)* = self;
				display! (formatter, $($args)*);
				::std::result::Result::Ok (())
			}
		}
	};

}