1#[macro_export]
2macro_rules! yamlette_compose {
3 ( ignore ; $ignored:tt ; $expr:tt ) => { $expr };
4
5 ( orchestra ; $orchestra:expr ; $volumes:tt ) => {{ $crate::yamlette_compose! ( volumes ; &$orchestra ; $volumes ; [ ] ; [ ] ) }};
6
7 ( size ; [# $( $style:expr ),* => $( $element:tt ),* ] ) => {{ $crate::yamlette_compose! ( size ; [ $( $element ),* ] ) }};
8
9 ( size ; [ $( $element:tt ),* ] ) => {{
10 let mut _size = 1;
11
12 $(
13 _size += $crate::yamlette_compose! ( size ; $element );
14 )*
15
16 _size
17 }};
18
19 ( size ; {# $( $style:expr ),* => $( $key:tt : $val:tt ),* } ) => {{ $crate::yamlette_compose! ( size ; { $( $key : $val ),* } ) }};
20
21 ( size ; { $( $key:tt : $val:tt ),* } ) => {{
22 let mut _size = 1;
23
24 $(
25 _size += $crate::yamlette_compose! ( size ; $key );
26 _size += $crate::yamlette_compose! ( size ; $val );
27 )*
28
29 _size
30 }};
31
32 ( size ; ( # $( $style:expr ),* => $elem:tt ) ) => {{ $crate::yamlette_compose! ( size ; $elem ) }};
33
34 ( size ; ( # $( $style:expr ),* => $elem:expr ) ) => {{ $crate::yamlette_compose! ( size ; $elem ) }};
35
36 ( size ; ( & $alias:ident $elem:tt ) ) => {{ $crate::yamlette_compose! ( size ; $elem ) }};
37
38 ( size ; ( & $alias:ident $elem:expr ) ) => {{ $crate::yamlette_compose! ( size ; $elem ) }};
39
40 ( size ; ( * $link:ident ) ) => {{ 1 }};
41
42 ( size ; ( $elem:tt ) ) => {{ $crate::yamlette_compose! ( size ; $elem ) }};
43
44 ( size ; ( $elem:expr ) ) => {{ $crate::yamlette_compose! ( size ; $elem ) }};
45
46 ( size ; $element:expr ) => {{
47 use $crate::orchestra::chord::Chord;
48 Chord::chord_size (&$element)
49 }};
50
51
52 ( directives ; $orchestra:expr ; $directives:tt ) => {{
53 let _tags_count = $crate::yamlette_compose! ( directives ; tags count ; $directives );
54
55 if _tags_count > 0 {
56 use std::borrow::Cow;
57
58 let mut _tags: Vec<(Cow<'static, str>, Cow<'static, str>)> = Vec::with_capacity (_tags_count);
59 $crate::yamlette_compose! ( directives ; collect tags ; _tags ; $directives );
60 $orchestra.directive_tags (_tags).ok ().unwrap ();
61 }
62
63 $crate::yamlette_compose! ( directives ; others ; $orchestra ; $directives );
64 }};
65
66 ( directives ; tags count ; [ $( $directive:tt ),* ] ) => {{
67 let mut _size = 0;
68 $( _size += $crate::yamlette_compose! ( directives ; tag count ; $directive ); )*
69 _size
70 }};
71
72 ( directives ; tag count ; (TAG ; $shortcut:expr , $handle:expr ) ) => { 1 };
73 ( directives ; tag count ; $directive:tt ) => { 0 };
74
75 ( directives ; collect tags ; $vec:expr ; [ $( $directive:tt ),* ] ) => { $( $crate::yamlette_compose! ( directive ; collect tags ; $vec ; $directive ); )* };
76 ( directive ; collect tags ; $vec:expr ; (TAG ; $shortcut:expr , $handle:expr ) ) => { $vec.push ( (Cow::from ($shortcut) , Cow::from ($handle)) ); };
77 ( directive ; collect tags ; $vec:expr ; $directive:tt ) => {{ }};
78
79 ( directives ; others ; $orchestra:expr ; [ $( $directive:tt ),* ] ) => {{ $( $crate::yamlette_compose! ( directive ; others ; $orchestra ; $directive ); )* }};
80 ( directive ; others ; $orchestra:expr ; YAML ) => {{ $orchestra.directive_yaml (true).ok ().unwrap (); }};
81 ( directive ; others ; $orchestra:expr ; NO_YAML ) => {{ $orchestra.directive_yaml (false).ok ().unwrap (); }};
82 ( directive ; others ; $orchestra:expr ; BORDER_TOP ) => {{ $orchestra.volume_border_top (true).ok ().unwrap (); }};
83 ( directive ; others ; $orchestra:expr ; NO_BORDER_TOP ) => {{ $orchestra.volume_border_top (false).ok ().unwrap (); }};
84 ( directive ; others ; $orchestra:expr ; BORDER_BOT ) => {{ $orchestra.volume_border_bot (true).ok ().unwrap (); }};
85 ( directive ; others ; $orchestra:expr ; NO_BORDER_BOT ) => {{ $orchestra.volume_border_bot (false).ok ().unwrap (); }};
86 ( directive ; others ; $orchestra:expr ; (TAG ; $shortcut:expr , $handle:expr ) ) => {};
87
88
89 ( styles ; [ $( $style:expr ),* ] ) => { [ $( &mut $style as &mut dyn $crate::model::style::Style ),* ] };
90
91 ( styles ; apply to common ; $common_styles:expr ; $styles:tt ) => {{
92 let mut cstyles = $common_styles;
93
94 let styles: &mut [ &mut dyn $crate::model::style::Style ] = &mut $crate::yamlette_compose! ( styles ; $styles );
95
96 for style in styles {
97 style.common_styles_apply (&mut cstyles);
98 }
99
100 cstyles
101 }};
102
103
104 ( volumes ; $orchestra:expr ; [ # $( $style:expr ),* => % $( $directive:tt ),* => $( $volume:tt ),* ] ; [ ] ; [ ] ) => {{
105 $crate::yamlette_compose! ( volumes ; $orchestra ; [ $( $volume ),* ] ; [ $( $style ),* ] ; [ $( $directive ),* ] )
106 }};
107
108
109 ( volumes ; $orchestra:expr ; [ % $( $directive:tt ),* => $( $volume:tt ),* ] ; [ ] ; [ ] ) => {{
110 $crate::yamlette_compose! ( volumes ; $orchestra ; [ $( $volume ),* ] ; [ ] ; [ $( $directive ),* ] )
111 }};
112
113
114 ( volumes ; $orchestra:expr ; [ # $( $style:expr ),* => $( $volume:tt ),* ] ; [ ] ; [ ] ) => {{
115 $crate::yamlette_compose! ( volumes ; $orchestra ; [ $( $volume ),* ] ; [ $( $style ),* ] ; [ ] )
116 }};
117
118
119 ( volumes ; $orchestra:expr ; [ $( $volume:tt ),* ] ; $styles:tt ; $directives:tt ) => {{
120 let mut _size = 0;
121
122 $( $crate::yamlette_compose! ( ignore ; $volume ; { _size += 1; } ); )*
123
124 $orchestra.volumes (_size).ok ().unwrap ();
125
126 let _common_styles = $orchestra.get_styles ();
127
128 $(
129 $crate::yamlette_compose! ( volume ; $orchestra ; _common_styles ; $volume ; $styles ; $directives );
130
131 $orchestra.vol_end ().ok ().unwrap ();
132 )*
133
134 $orchestra.the_end ().ok ().unwrap ();
135 }};
136
137
138 ( volume ; $orchestra:expr ; $common_styles:expr ; [ # $( $style:expr ),+ => % $( $directive:tt ),+ => $( $rule:tt ),* ] ; [ ] ; [ ] ) => {{
139 $crate::yamlette_compose! ( volume ; $orchestra ; $common_styles ; [ $( $rule ),* ] ; [ $( $style ),* ] ; [ $( $directive ),* ] );
140 }};
141
142 ( volume ; $orchestra:expr ; $common_styles:expr ; [ # $( $style:expr ),+ => % $( $directive:tt ),+ => $( $rule:tt ),* ] ; [ $( $parent_style:expr ),* ] ; [ ] ) => {{
143 $crate::yamlette_compose! ( volume ; $orchestra ; $common_styles ; [ $( $rule ),* ] ; [ $( $parent_style ),* , $( $style ),* ] ; [ $( $directive ),* ] );
144 }};
145
146
147 ( volume ; $orchestra:expr ; $common_styles:expr ; [ # $( $style:expr ),+ => % $( $directive:tt ),+ => $( $rule:tt ),* ] ; [ ] ; [ $( $parent_directive:tt ),* ] ) => {{
148 $crate::yamlette_compose! ( volume ; $orchestra ; $common_styles ; [ $( $rule ),* ] ; [ $( $style ),* ] ; [ $( $parent_directive ),* , $( $directive ),* ] );
149 }};
150
151
152 ( volume ; $orchestra:expr ; $common_styles:expr ; [ # $( $style:expr ),+ => % $( $directive:tt ),+ => $( $rule:tt ),* ] ; [ $( $parent_style:expr ),* ] ; [ $( $parent_directive:tt ),* ] ) => {{
153 $crate::yamlette_compose! ( volume ; $orchestra ; $common_styles ; [ $( $rule ),* ] ; [ $( $parent_style ),* , $( $style ),* ] ; [ $( $parent_directive ),* , $( $directive ),* ] );
154 }};
155
156
157 ( volume ; $orchestra:expr ; $common_styles:expr ; [ % $( $directive:tt ),* => $( $rule:tt ),* ] ; $styles:tt ; [ ] ) => {{
158 $crate::yamlette_compose! ( volume ; $orchestra ; $common_styles ; [ $( $rule ),* ] ; $styles ; [ $( $directive ),* ] );
159 }};
160
161
162 ( volume ; $orchestra:expr ; $common_styles:expr ; [ % $( $directive:tt ),* => $( $rule:tt ),* ] ; $styles:tt ; [ $( $parent_directive:tt ),* ] ) => {{
163 $crate::yamlette_compose! ( volume ; $orchestra ; $common_styles ; [ $( $rule ),* ] ; $styles ; [ $( $parent_directive ),* , $( $directive ),* ] );
164 }};
165
166
167 ( volume ; $orchestra:expr ; $common_styles:expr ; [ # $( $style:expr ),* => $( $rule:tt ),* ] ; [ ] ; $directives:tt ) => {{
168 $crate::yamlette_compose! ( volume ; $orchestra ; $common_styles ; [ $( $rule ),* ] ; [ $( $style ),* ] ; $directives );
169 }};
170
171
172 ( volume ; $orchestra:expr ; $common_styles:expr ; [ # $( $style:expr ),* => $( $rule:tt ),* ] ; [ $( $parent_style:expr ),* ] ; $directives:tt ) => {{
173 $crate::yamlette_compose! ( volume ; $orchestra ; $common_styles ; [ $( $rule ),* ] ; [ $( $parent_style ),* , $( $style ),* ] ; $directives );
174 }};
175
176
177 ( volume ; $orchestra:expr ; $common_styles:expr ; [ $( $rules:tt ),* ] ; $styles:tt ; $directives:tt ) => {{
178 let mut _size = 0;
179
180 $orchestra.vol_next ().ok ().unwrap ();
181
182 $crate::yamlette_compose! ( directives ; $orchestra ; $directives );
183
184 $( $crate::yamlette_compose! ( ignore ; $rules ; { _size += $crate::yamlette_compose! ( size ; $rules ); } ); )*
185
186 $orchestra.vol_reserve (_size).ok ().unwrap ();
187
188 let _common_styles = $crate::yamlette_compose! ( styles ; apply to common ; $common_styles ; $styles );
189
190 $(
191 $crate::yamlette_compose! ( play ; $orchestra ; 0 ; $rules ; _common_styles ; $styles ; None );
192 )*
193 }};
194
195
196 ( play ; $orchestra:expr ; $level:expr ; [ # $( $style:expr ),* => $( $element:tt ),* ] ; $common_styles:expr ; [] ; $alias:expr ) => {{
197 $crate::yamlette_compose! ( play ; $orchestra ; $level ; [ $( $element ),* ] ; $common_styles ; [ $( $style ),* ] ; $alias )
198 }};
199
200
201 ( play ; $orchestra:expr ; $level:expr ; [ # $( $style:expr ),* => $( $element:tt ),* ] ; $common_styles:expr ; [ $( $parent_style:expr ),+ ] ; $alias:expr ) => {{
202 $crate::yamlette_compose! ( play ; $orchestra ; $level ; [ $( $element ),* ] ; $common_styles ; [ $( $parent_style ),* , $( $style ),* ] ; $alias )
203 }};
204
205
206 ( play ; $orchestra:expr ; $level:expr ; [ $( $element:tt ),* ] ; $common_styles:expr ; $styles:tt ; $alias:expr ) => {{
207 use $crate::orchestra::chord::{ Chord, EmptyList };
208
209 let styles: &mut [ &mut dyn $crate::model::style::Style ] = &mut $crate::yamlette_compose! ( styles ; $styles );
210
211 Chord::play (EmptyList, $orchestra, $level, $alias, $common_styles, styles).ok ().unwrap ();
212
213 let _common_styles = $crate::yamlette_compose! ( styles ; apply to common ; $common_styles ; $styles );
214
215 $(
216 $crate::yamlette_compose! ( play ; $orchestra ; $level + 1 ; $element ; _common_styles ; $styles ; None );
217 )*
218 }};
219
220
221 ( play ; $orchestra:expr ; $level:expr ; { # $( $style:expr ),* => $( $key:tt : $val:tt ),* } ; $common_styles:expr ; [] ; $alias:expr ) => {{
222 $crate::yamlette_compose! ( play ; $orchestra ; $level ; { $( $key : $val ),* } ; $common_styles ; [ $( $style ),* ] ; $alias )
223 }};
224
225
226 ( play ; $orchestra:expr ; $level:expr ; { # $( $style:expr ),* => $( $key:tt : $val:tt ),* } ; $common_styles:expr ; [ $( $parent_style:expr ),+ ] ; $alias:expr ) => {{
227 $crate::yamlette_compose! ( play ; $orchestra ; $level ; { $( $key : $val ),* } ; $common_styles ; [ $( $parent_style ),* , $( $style ),* ] ; $alias )
228 }};
229
230
231 ( play ; $orchestra:expr ; $level:expr ; { $( $key:tt : $val:tt ),* } ; $common_styles:expr ; $styles:tt ; $alias:expr ) => {{
232 use $crate::orchestra::chord::{ Chord, EmptyDict };
233
234 let styles: &mut [ &mut dyn $crate::model::style::Style ] = &mut $crate::yamlette_compose! ( styles ; $styles );
235
236 Chord::play (EmptyDict, $orchestra, $level, $alias, $common_styles, styles).ok ().unwrap ();
237
238 let _common_styles = $crate::yamlette_compose! ( styles ; apply to common ; $common_styles ; $styles );
239
240 $(
241 $crate::yamlette_compose! ( play ; $orchestra ; $level + 1 ; $key ; _common_styles ; $styles ; None );
242 $crate::yamlette_compose! ( play ; $orchestra ; $level + 1 ; $val ; _common_styles ; $styles ; None );
243 )*
244 }};
245
246
247 ( play ; $orchestra:expr ; $level:expr ; ( # $( $style:expr ),* => $element:tt ) ; $common_styles:expr ; [ ] ; $alias:expr ) => {{
248 let _common_styles = $crate::yamlette_compose! ( styles ; apply to common ; $common_styles ; [ $( $style ),* ] );
249
250 $crate::yamlette_compose! ( play ; $orchestra ; $level ; $element ; _common_styles ; [ $( $style ),* ] ; $alias );
251 }};
252
253 ( play ; $orchestra:expr ; $level:expr ; ( # $( $style:expr ),* => $element:tt ) ; $common_styles:expr ; [ $( $parent_style:expr ),* ] ; $alias:expr ) => {{
254 let _common_styles = $crate::yamlette_compose! ( styles ; apply to common ; $common_styles ; [ $( $style ),* ] );
255
256 $crate::yamlette_compose! ( play ; $orchestra ; $level ; $element ; _common_styles ; [ $( $parent_style ),* , $( $style ),* ] ; $alias );
257 }};
258
259 ( play ; $orchestra:expr ; $level:expr ; ( # $( $style:expr ),* => $element:expr ) ; $common_styles:expr ; [ ] ; $alias:expr ) => {{
260 let _common_styles = $crate::yamlette_compose! ( styles ; apply to common ; $common_styles ; [ $( $style ),* ] );
261
262 $crate::yamlette_compose! ( play ; $orchestra ; $level ; $element ; _common_styles ; [ $( $style ),* ] ; $alias );
263 }};
264
265 ( play ; $orchestra:expr ; $level:expr ; ( # $( $style:expr ),* => $element:expr ) ; $common_styles:expr ; [ $( $parent_style:expr ),* ] ; $alias:expr ) => {{
266 let _common_styles = $crate::yamlette_compose! ( styles ; apply to common ; $common_styles ; [ $( $style ),* ] );
267
268 $crate::yamlette_compose! ( unit ; $orchestra ; $level ; $element ; _common_styles ; [ $( $parent_style ),* , $( $style ),* ] ; $alias );
269 }};
270
271 ( play ; $orchestra:expr ; $level:expr ; ( & $new_alias:ident $element:tt ) ; $common_styles:expr ; $styles:tt ; $alias:expr ) => {{
272 use std::borrow::Cow;
273 $crate::yamlette_compose! ( play ; $orchestra ; $level ; $element ; $common_styles ; $styles ; Some (Cow::from (stringify! ($new_alias))) );
274 }};
275
276 ( play ; $orchestra:expr ; $level:expr ; ( & $new_alias:ident $element:expr ) ; $common_styles:expr ; $styles:tt ; $alias:expr ) => {{
277 use std::borrow::Cow;
278 $crate::yamlette_compose! ( play ; $orchestra ; $level ; $element ; $common_styles ; $styles ; Some (Cow::from (stringify! ($new_alias))) );
279 }};
280
281 ( play ; $orchestra:expr ; $level:expr ; ( * $link:ident ) ; $common_styles:expr ; $styles:tt ; $alias:expr ) => {{
282 use $crate::model::yamlette::literal::LiteralValue;
283 use $crate::model::TaggedValue;
284 $orchestra.play ($level, TaggedValue::from (LiteralValue::from (format! ("*{}", stringify! ($link))))).ok ().unwrap ();
285 }};
286
287 ( play ; $orchestra:expr ; $level:expr ; ( $element:tt ) ; $common_styles:expr ; $styles:tt ; $alias:expr ) => {{
288 $crate::yamlette_compose! ( play ; $orchestra ; $level ; $element ; $common_styles ; $styles ; $alias );
289 }};
290
291 ( play ; $orchestra:expr ; $level:expr ; ( $element:expr ) ; $common_styles:expr ; $styles:tt ; $alias:expr ) => {{
292 $crate::yamlette_compose! ( unit ; $orchestra ; $level ; $element ; $common_styles ; $styles ; $alias );
293 }};
294
295
296 ( play ; $orchestra:expr ; $level:expr ; $element:expr ; $common_styles:expr ; $styles:tt ; $alias:expr ) => {{
297 $crate::yamlette_compose! ( unit ; $orchestra ; $level ; $element ; $common_styles ; $styles ; $alias );
298 }};
299
300
301 ( unit ; $orchestra:expr ; $level:expr ; $element:expr ; $common_styles:expr ; $styles:tt ; $alias:expr ) => {{
302 use $crate::orchestra::chord::Chord;
303
304 let styles: &mut [ &mut dyn $crate::model::style::Style ] = &mut $crate::yamlette_compose! ( styles ; $styles );
305
306 Chord::play ($element, $orchestra, $level, $alias, $common_styles, styles).ok ().unwrap ()
307 }};
308}
309
310#[cfg(all(test, not(feature = "dev")))]
311mod tests {
312 #[test]
313 fn size() {
314 let size = yamlette_compose! ( size ; "halo" );
315 assert_eq!(1, size);
316
317 let size = yamlette_compose! ( size ; () );
318 assert_eq!(1, size);
319
320 let size = yamlette_compose! ( size ; [ (), 1, "2", [ 4, { "a": 1, "b": 4 }, 3 ], () ] );
321 assert_eq!(13, size);
322 }
323}