syn_lite/
lib.rs

1#![no_std]
2
3#[macro_export]
4macro_rules! expand_or {
5    ([] $($or:tt)*  ) => { $($or)* };
6    ([$($expand:tt)+] $($or:tt)* ) => { $($expand)+ };
7}
8
9#[macro_export]
10macro_rules! expand_if_else {
11    ([] $then:tt {$($else:tt)*}  ) => { $($else)* };
12    ([$($if:tt)+] {$($then:tt)*} $else:tt ) => { $($then)* };
13}
14
15// region: common utils
16
17#[doc(hidden)]
18#[macro_export]
19macro_rules! __start_parsing_with {
20    (
21        parse_with {$($parse_with:tt)*}
22        args {
23            on_finish $on_finish:tt
24            $(prepend $output_prepend:tt)?
25            input $input:tt
26            $(append $output_append:tt)?
27        }
28        $(after_input { $($after_input:tt)* })?
29    ) => {
30        $($parse_with)* {
31            {} // initial state
32            $input
33            $input // clone input
34            $($($after_input)*)?
35            {
36                on_finish $on_finish
37                $(prepend $output_prepend)?
38                $(append $output_append)?
39            } // on finish
40        }
41    };
42}
43
44// this doesn't change the order of tokens
45#[doc(hidden)]
46#[macro_export]
47macro_rules! __start_parsing_with_v2 {
48    (
49        parse_with {$($parse_with:tt)*}
50        $(before_input { $($before_input:tt)* })?
51        args {
52            on_finish $on_finish:tt
53            $(prepend $output_prepend:tt)?
54            input $input:tt
55            $(append $output_append:tt)?
56        }
57        $(after_input { $($after_input:tt)* })?
58    ) => {
59        $($parse_with)* {
60            {
61                on_finish $on_finish
62                $(prepend $output_prepend)?
63            }
64            $($($before_input)*)?
65            $input
66            $input // clone input
67            $($($after_input)*)?
68            {
69                $(append $output_append)?
70            }
71        }
72    };
73}
74
75#[doc(hidden)]
76#[macro_export]
77macro_rules! __resolve_finish_v2 {
78    (
79        {
80            on_finish { $($macro_and_bang:tt)* }
81            $(prepend { $($output_prepend:tt)* })?
82        }
83        { $($output:tt)* }
84        { $(append  { $($output_append:tt )* })? }
85    ) => {
86        $($macro_and_bang)* {
87            $($($output_prepend)*)?
88            $($output)*
89            $($($output_append)*)?
90        }
91    };
92}
93
94#[doc(hidden)]
95#[macro_export]
96macro_rules! __resolve_finish {
97    (
98        on_finish {
99            on_finish { $($macro_and_bang:tt)* }
100            $(prepend { $($output_prepend:tt)* })?
101            $(append  { $($output_append:tt )* })?
102        }
103        output { $($output:tt)* }
104    ) => {
105        $($macro_and_bang)* {
106            $($($output_prepend)*)?
107            $($output)*
108            $($($output_append)*)?
109        }
110    };
111}
112
113#[doc(hidden)]
114#[macro_export]
115macro_rules! __resolve_finish_flat {
116    (
117        $finish:tt
118        $($output:tt)*
119    ) => {
120        $crate::__resolve_finish! {
121            on_finish $finish
122            output { $($output)* }
123        }
124    };
125}
126
127// endregion
128
129// region: consume_till_outer_gt
130
131/// Consume tokens till an outer `>`.
132///
133/// `>` is considered an outer `>` if there is not a previous `<` matching it.
134///
135/// Note that this macro might split the following tokens
136/// if the last `>` is an outer `>` which doesn't have a matched previous `>`:
137/// - `=>`
138/// - `>=`
139/// - `>>`
140/// - `>>=`
141///
142/// The `>` in `->` is not considered as a splitted `>`.
143#[macro_export]
144macro_rules! consume_till_outer_gt {
145    ($($args:tt)*) => {
146        $crate::__start_parsing_with! {
147            parse_with { $crate::__impl_consume_till_outer_gt! }
148            args {
149                $($args)*
150            }
151            after_input {
152                [] // inner `<` list, start with an empty list
153            }
154        }
155    };
156}
157
158#[doc(hidden)]
159#[macro_export]
160macro_rules! __impl_consume_till_outer_gt {
161    // region: unmatched > or >>
162    // >
163    (
164        $consumed:tt
165        {> $($_rest:tt)*}
166        $rest:tt
167        [] // no inner `<` before this `>`
168        $finish:tt
169    ) => {
170        $crate::__resolve_finish! {
171            on_finish $finish
172            output {
173                before_gt $consumed
174                gt_and_rest $rest
175            }
176        }
177    };
178    // >=
179    (
180        $consumed:tt
181        {>= $($_rest:tt)*}
182        $rest:tt
183        [] // no inner `<` before this `>`
184        $finish:tt
185    ) => {
186        $crate::__resolve_finish! {
187            on_finish $finish
188            output {
189                before_gt $consumed
190                gt_and_rest $rest
191            }
192        }
193    };
194    // =>
195    (
196        {$($consumed:tt)*}
197        {=> $($rest:tt)*}
198        $_rest:tt
199        [] // no inner `<` before this `>`
200        $finish:tt
201    ) => {
202        $crate::__resolve_finish! {
203            on_finish $finish
204            output {
205                before_gt { $($consumed)* = } // split
206                gt_and_rest { > $($rest)* } // split
207            }
208        }
209    };
210    // >> only one matched
211    (
212        {$($consumed:tt)*}
213        {>> $($_rest:tt)*}
214        {>> $($rest:tt )*}
215        [<] // no inner `<` before the second `>`
216        $finish:tt
217    ) => {
218        $crate::__resolve_finish! {
219            on_finish $finish
220            output {
221                before_gt {$($consumed)* >}
222                gt_and_rest { > $($rest)* }
223            }
224        }
225    };
226    // >> neither matched
227    (
228        $consumed:tt
229        {>>    $($_rest:tt)*}
230        $rest:tt
231        [] // no inner `<` before the first `>`
232        $finish:tt
233    ) => {
234        $crate::__resolve_finish! {
235            on_finish $finish
236            output {
237                before_gt $consumed
238                gt_and_rest $rest
239            }
240        }
241    };
242    // >>= only one matched
243    (
244        {$($consumed:tt)*}
245        {>>= $($_rest:tt)*}
246        {>>= $($rest:tt )*}
247        [<] // no inner `<` before the second `>`
248        $finish:tt
249    ) => {
250        $crate::__resolve_finish! {
251            on_finish $finish
252            output {
253                before_gt {$($consumed)* >}
254                gt_and_rest { >= $($rest)* } // split >>= to > and >=
255            }
256        }
257    };
258    // >>= neither matched
259    (
260        $consumed:tt
261        {>>=   $($_rest:tt)*}
262        $rest:tt
263        [] // no inner `<` before the first `>`
264        $finish:tt
265    ) => {
266        $crate::__resolve_finish! {
267            on_finish $finish
268            output {
269                before_gt $consumed
270                gt_and_rest $rest
271            }
272        }
273    };
274    // endregion
275
276    // region: < and <<
277    // <
278    (
279        {$($consumed:tt)*}
280        {<     $($_rest:tt)*}
281        {$t:tt $($rest:tt )*}
282        [$($got_lt:tt)*]
283        $finish:tt
284    ) => {
285        $crate::__impl_consume_till_outer_gt! {
286            {$($consumed)* $t}
287            {$($rest)*}
288            {$($rest)*}
289            [$($got_lt)* $t]
290            $finish
291        }
292    };
293    // <-
294    (
295        {$($consumed:tt)*}
296        {<-    $($_rest:tt)*}
297        {$t:tt $($rest:tt )*}
298        [$($got_lt:tt)*]
299        $finish:tt
300    ) => {
301        $crate::__impl_consume_till_outer_gt! {
302            {$($consumed)* $t}
303            {$($rest)*}
304            {$($rest)*}
305            [$($got_lt)* <]
306            $finish
307        }
308    };
309    // <=
310    (
311        {$($consumed:tt)*}
312        {<=    $($_rest:tt)*}
313        {$t:tt $($rest:tt )*}
314        [$($got_lt:tt)*]
315        $finish:tt
316    ) => {
317        $crate::__impl_consume_till_outer_gt! {
318            {$($consumed)* $t}
319            {$($rest)*}
320            {$($rest)*}
321            [$($got_lt)* <]
322            $finish
323        }
324    };
325    // <<
326    (
327        {$($consumed:tt)*}
328        {<<    $($_rest:tt)*}
329        {$t:tt $($rest:tt )*}
330        [$($got_lt:tt)*]
331        $finish:tt
332    ) => {
333        $crate::__impl_consume_till_outer_gt! {
334            {$($consumed)* $t}
335            {$($rest)*}
336            {$($rest)*}
337            [$($got_lt)* < <] // split `<<` into two `<`
338            $finish
339        }
340    };
341    // <<=
342    (
343        {$($consumed:tt)*}
344        {<<=   $($_rest:tt)*}
345        {$t:tt $($rest:tt )*}
346        [$($got_lt:tt)*]
347        $finish:tt
348    ) => {
349        $crate::__impl_consume_till_outer_gt! {
350            {$($consumed)* $t}
351            {$($rest)*}
352            {$($rest)*}
353            [$($got_lt)* < <] // split `<<` into two `<`
354            $finish
355        }
356    };
357    // endregion
358
359    // region: `>` matched a previous `<` or `>>` matched previous `<<`
360    // `>` matched a previous `<`
361    (
362        {$($consumed:tt)*}
363        {>     $($_rest:tt)*}
364        {$t:tt $($rest:tt )*}
365        [< $($got_lt:tt)*]
366        $finish:tt
367    ) => {
368        $crate::__impl_consume_till_outer_gt! {
369            {$($consumed)* $t}
370            {$($rest)*}
371            {$($rest)*}
372            [$($got_lt)*]
373            $finish
374        }
375    };
376    // `>=` matched a previous `<`
377    (
378        {$($consumed:tt)*}
379        {>=    $($_rest:tt)*}
380        {$t:tt $($rest:tt )*}
381        [< $($got_lt:tt)*]
382        $finish:tt
383    ) => {
384        $crate::__impl_consume_till_outer_gt! {
385            {$($consumed)* $t}
386            {$($rest)*}
387            {$($rest)*}
388            [$($got_lt)*]
389            $finish
390        }
391    };
392    // `=>` matched a previous `<`
393    (
394        {$($consumed:tt)*}
395        {=>    $($_rest:tt)*}
396        {$t:tt $($rest:tt )*}
397        [< $($got_lt:tt)*]
398        $finish:tt
399    ) => {
400        $crate::__impl_consume_till_outer_gt! {
401            {$($consumed)* $t}
402            {$($rest)*}
403            {$($rest)*}
404            [$($got_lt)*]
405            $finish
406        }
407    };
408    // `>>` matches two previous `<`
409    (
410        {$($consumed:tt)*}
411        {>>    $($_rest:tt)*}
412        {$t:tt $($rest:tt )*}
413        [< < $($got_lt:tt)*]
414        $finish:tt
415    ) => {
416        $crate::__impl_consume_till_outer_gt! {
417            {$($consumed)* $t}
418            {$($rest)*}
419            {$($rest)*}
420            [$($got_lt)*]
421            $finish
422        }
423    };
424    // `>>=` matches two previous `<`
425    (
426        {$($consumed:tt)*}
427        {>>=   $($_rest:tt)*}
428        {$t:tt $($rest:tt )*}
429        [< < $($got_lt:tt)*]
430        $finish:tt
431    ) => {
432        $crate::__impl_consume_till_outer_gt! {
433            {$($consumed)* $t}
434            {$($rest)*}
435            {$($rest)*}
436            [$($got_lt)*]
437            $finish
438        }
439    };
440    // endregion
441
442    // anything else
443    (
444        {$($consumed:tt)*}
445        $_rest:tt
446        {$t:tt $($rest:tt)*}
447        $got_lt:tt
448        $finish:tt
449    ) => {
450        $crate::__impl_consume_till_outer_gt! {
451            {$($consumed)* $t}
452            {$($rest)*}
453            {$($rest)*}
454            $got_lt
455            $finish
456        }
457    };
458}
459
460#[doc(hidden)]
461#[macro_export]
462macro_rules! __impl_split_gt_and_rest {
463    (
464        {>      $($_rest:tt)*}
465        {$gt:tt $($rest:tt )*}
466        $finish:tt
467    ) => {
468        $crate::__resolve_finish! {
469            on_finish $finish
470            output {
471                gt {$gt}
472                rest {$($rest)*}
473            }
474        }
475    };
476    (
477        {>= $($rest:tt)*}
478        $_rest:tt
479        $finish:tt
480    ) => {
481        $crate::__resolve_finish! {
482            on_finish $finish
483            output {
484                gt {>}
485                rest { = $($rest)* } // >= is splitted into > and =
486            }
487        }
488    };
489    (
490        {>> $($rest:tt)*}
491        $_rest:tt
492        $finish:tt
493    ) => {
494        $crate::__resolve_finish! {
495            on_finish $finish
496            output {
497                gt {>}
498                rest { > $($rest)* } // >> is splitted into > and >
499            }
500        }
501    };
502    (
503        {>>= $($rest:tt)*}
504        $_rest:tt
505        $finish:tt
506    ) => {
507        $crate::__resolve_finish! {
508            on_finish $finish
509            output {
510                gt {>}
511                rest { >= $($rest)* } // >>= is splitted into > and >=
512            }
513        }
514    };
515}
516// endregion
517
518// region: consume_till_outer_gt_inclusive
519
520/// Consume tokens till an outer `>`, and consume this `>` as well.
521///
522/// See [consume_till_outer_gt!] for what is an outer `>`.
523#[macro_export]
524macro_rules! consume_till_outer_gt_inclusive {
525    ($($args:tt)*) => {
526        $crate::__start_parsing_with! {
527            parse_with { $crate::__impl_consume_till_outer_gt_inclusive! }
528            args {
529                $($args)*
530            }
531            after_input {
532                [] // inner `<` list, start with an empty list
533            }
534        }
535    };
536}
537
538#[doc(hidden)]
539#[macro_export]
540macro_rules! __impl_consume_till_outer_gt_inclusive {
541    // region: unmatched > or >>
542    // >
543    (
544        {$($consumed:tt)*}
545        {>      $($_rest:tt)*}
546        {$gt:tt $($rest:tt )*}
547        [] // no inner `<` before this `>`
548        $finish:tt
549    ) => {
550        $crate::__resolve_finish! {
551            on_finish $finish
552            output {
553                before_and_gt {$($consumed)* $gt}
554                after_gt {$($rest)*}
555            }
556        }
557    };
558    // >=
559    (
560        {$($consumed:tt)*}
561        {>=     $($rest:tt)*}
562        $_rest:tt
563        [] // no inner `<` before this `>`
564        $finish:tt
565    ) => {
566        $crate::__resolve_finish! {
567            on_finish $finish
568            output {
569                before_and_gt { $($consumed)* > } // >= is splitted
570                after_gt { = $($rest)* }
571            }
572        }
573    };
574    // =>
575    (
576        {$($consumed:tt)*}
577        {=>     $($_rest:tt)*}
578        {$gt:tt $($rest:tt )*}
579        [] // no inner `<` before this `>`
580        $finish:tt
581    ) => {
582        $crate::__resolve_finish! {
583            on_finish $finish
584            output {
585                before_and_gt {$($consumed)* $gt}
586                after_gt {$($rest)*}
587            }
588        }
589    };
590    // >> only one matched
591    (
592        {$($consumed:tt)*}
593        {>>        $($_rest:tt)*}
594        {$gt_gt:tt $($rest:tt )*}
595        [<] // no inner `<` before the second `>`
596        $finish:tt
597    ) => {
598        $crate::__resolve_finish! {
599            on_finish $finish
600            output {
601                before_and_gt {$($consumed)* $gt_gt}
602                after_gt { $($rest)* }
603            }
604        }
605    };
606    // >> neither matched
607    (
608        {$($consumed:tt)*}
609        {>>    $($rest:tt)*}
610        $_rest:tt
611        [] // no inner `<` before the first `>`
612        $finish:tt
613    ) => {
614        $crate::__resolve_finish! {
615            on_finish $finish
616            output {
617                before_and_gt {$($consumed)* >} // >> is splitted
618                after_gt { > $($rest)*}
619            }
620        }
621    };
622    // >>= only one matched
623    (
624        {$($consumed:tt)*}
625        {>>= $($_rest:tt)*}
626        {>>= $($rest:tt )*}
627        [<] // no inner `<` before the second `>`
628        $finish:tt
629    ) => {
630        $crate::__resolve_finish! {
631            on_finish $finish
632            output {
633                before_and_gt {$($consumed)* >>}
634                after_gt { = $($rest)* } // >>= is splitted
635            }
636        }
637    };
638    // >>= neither matched
639    (
640        {$($consumed:tt)*}
641        {>>= $($rest:tt)*}
642        $_rest:tt
643        [] // no inner `<` before the first `>`
644        $finish:tt
645    ) => {
646        $crate::__resolve_finish! {
647            on_finish $finish
648            output {
649                before_and_gt {$($consumed)* >}
650                after_gt { >= $($rest)* } // >>= is splitted
651            }
652        }
653    };
654    // endregion
655
656    // region: < and <<
657    // <
658    (
659        {$($consumed:tt)*}
660        {<     $($_rest:tt)*}
661        {$t:tt $($rest:tt )*}
662        [$($got_lt:tt)*]
663        $finish:tt
664    ) => {
665        $crate::__impl_consume_till_outer_gt_inclusive! {
666            {$($consumed)* $t}
667            {$($rest)*}
668            {$($rest)*}
669            [$($got_lt)* $t]
670            $finish
671        }
672    };
673    // <-
674    (
675        {$($consumed:tt)*}
676        {<-    $($_rest:tt)*}
677        {$t:tt $($rest:tt )*}
678        [$($got_lt:tt)*]
679        $finish:tt
680    ) => {
681        $crate::__impl_consume_till_outer_gt_inclusive! {
682            {$($consumed)* $t}
683            {$($rest)*}
684            {$($rest)*}
685            [$($got_lt)* <]
686            $finish
687        }
688    };
689    // <=
690    (
691        {$($consumed:tt)*}
692        {<=    $($_rest:tt)*}
693        {$t:tt $($rest:tt )*}
694        [$($got_lt:tt)*]
695        $finish:tt
696    ) => {
697        $crate::__impl_consume_till_outer_gt_inclusive! {
698            {$($consumed)* $t}
699            {$($rest)*}
700            {$($rest)*}
701            [$($got_lt)* <]
702            $finish
703        }
704    };
705    // <<
706    (
707        {$($consumed:tt)*}
708        {<<    $($_rest:tt)*}
709        {$t:tt $($rest:tt )*}
710        [$($got_lt:tt)*]
711        $finish:tt
712    ) => {
713        $crate::__impl_consume_till_outer_gt_inclusive! {
714            {$($consumed)* $t}
715            {$($rest)*}
716            {$($rest)*}
717            [$($got_lt)* < <] // split `<<` into two `<`
718            $finish
719        }
720    };
721    // <<=
722    (
723        {$($consumed:tt)*}
724        {<<=   $($_rest:tt)*}
725        {$t:tt $($rest:tt )*}
726        [$($got_lt:tt)*]
727        $finish:tt
728    ) => {
729        $crate::__impl_consume_till_outer_gt_inclusive! {
730            {$($consumed)* $t}
731            {$($rest)*}
732            {$($rest)*}
733            [$($got_lt)* < <] // split `<<` into two `<`
734            $finish
735        }
736    };
737    // endregion
738
739    // region: `>` matched a previous `<` or `>>` matched previous `<<`
740    // `>` matched a previous `<`
741    (
742        {$($consumed:tt)*}
743        {>     $($_rest:tt)*}
744        {$t:tt $($rest:tt )*}
745        [< $($got_lt:tt)*]
746        $finish:tt
747    ) => {
748        $crate::__impl_consume_till_outer_gt_inclusive! {
749            {$($consumed)* $t}
750            {$($rest)*}
751            {$($rest)*}
752            [$($got_lt)*]
753            $finish
754        }
755    };
756    // `>=` matched a previous `<`
757    (
758        {$($consumed:tt)*}
759        {>=    $($_rest:tt)*}
760        {$t:tt $($rest:tt )*}
761        [< $($got_lt:tt)*]
762        $finish:tt
763    ) => {
764        $crate::__impl_consume_till_outer_gt_inclusive! {
765            {$($consumed)* $t}
766            {$($rest)*}
767            {$($rest)*}
768            [$($got_lt)*]
769            $finish
770        }
771    };
772    // `=>` matched a previous `<`
773    (
774        {$($consumed:tt)*}
775        {=>    $($_rest:tt)*}
776        {$t:tt $($rest:tt )*}
777        [< $($got_lt:tt)*]
778        $finish:tt
779    ) => {
780        $crate::__impl_consume_till_outer_gt_inclusive! {
781            {$($consumed)* $t}
782            {$($rest)*}
783            {$($rest)*}
784            [$($got_lt)*]
785            $finish
786        }
787    };
788    // `>>` matches two previous `<`
789    (
790        {$($consumed:tt)*}
791        {>>    $($_rest:tt)*}
792        {$t:tt $($rest:tt )*}
793        [< < $($got_lt:tt)*]
794        $finish:tt
795    ) => {
796        $crate::__impl_consume_till_outer_gt_inclusive! {
797            {$($consumed)* $t}
798            {$($rest)*}
799            {$($rest)*}
800            [$($got_lt)*]
801            $finish
802        }
803    };
804    // `>>=` matches two previous `<`
805    (
806        {$($consumed:tt)*}
807        {>>=   $($_rest:tt)*}
808        {$t:tt $($rest:tt )*}
809        [< < $($got_lt:tt)*]
810        $finish:tt
811    ) => {
812        $crate::__impl_consume_till_outer_gt_inclusive! {
813            {$($consumed)* $t}
814            {$($rest)*}
815            {$($rest)*}
816            [$($got_lt)*]
817            $finish
818        }
819    };
820    // endregion
821
822    // anything else
823    (
824        {$($consumed:tt)*}
825        $_rest:tt
826        {$t:tt $($rest:tt)*}
827        $got_lt:tt
828        $finish:tt
829    ) => {
830        $crate::__impl_consume_till_outer_gt_inclusive! {
831            {$($consumed)* $t}
832            {$($rest)*}
833            {$($rest)*}
834            $got_lt
835            $finish
836        }
837    };
838}
839
840// endregion
841
842// region: consume_bounds
843
844/// Consume tokens till one of the following tokens:
845/// - `;`
846/// - an outer `,` (not wrapped in `< >`)
847/// - `where`
848/// - an outer `>` (See [consume_till_outer_gt!] for what an outer `>` is.)
849/// - an outer `=` (not wrapped in `< >`)
850/// - an outer `{..}` (not wrapped in `< >`)
851/// - EOF
852#[macro_export]
853macro_rules! consume_bounds {
854    ($($args:tt)*) => {
855        $crate::__start_parsing_with! {
856            parse_with { $crate::__impl_consume_bounds! }
857            args {
858                $($args)*
859            }
860        }
861    };
862}
863
864#[doc(hidden)]
865#[macro_export]
866macro_rules! __impl_consume_bounds {
867    // ,
868    (
869        $parsed_bounds:tt
870        {, $($after:tt)*}
871        $rest:tt
872        $finish:tt
873    ) => {
874        $crate::__resolve_finish! {
875            on_finish $finish
876            output {
877                consumed_bounds $parsed_bounds
878                rest $rest
879            }
880        }
881    };
882    // ;
883    (
884        $parsed_bounds:tt
885        {; $($after:tt)*}
886        $rest:tt
887        $finish:tt
888    ) => {
889        $crate::__resolve_finish! {
890            on_finish $finish
891            output {
892                consumed_bounds $parsed_bounds
893                rest $rest
894            }
895        }
896    };
897    // where
898    (
899        $parsed_bounds:tt
900        {where $($after:tt)*}
901        $rest:tt
902        $finish:tt
903    ) => {
904        $crate::__resolve_finish! {
905            on_finish $finish
906            output {
907                consumed_bounds $parsed_bounds
908                rest $rest
909            }
910        }
911    };
912    // an outer =
913    (
914        $parsed_bounds:tt
915        {= $($after:tt)*}
916        $rest:tt
917        $finish:tt
918    ) => {
919        $crate::__resolve_finish! {
920            on_finish $finish
921            output {
922                consumed_bounds $parsed_bounds
923                rest $rest
924            }
925        }
926    };
927    // {..}
928    (
929        $parsed_bounds:tt
930        {{$($_t:tt)*} $($after:tt)*}
931        $rest:tt
932        $finish:tt
933    ) => {
934        $crate::__resolve_finish! {
935            on_finish $finish
936            output {
937                consumed_bounds $parsed_bounds
938                rest $rest
939            }
940        }
941    };
942    // EOF
943    (
944        $parsed_bounds:tt
945        {} // EOF
946        $rest:tt
947        $finish:tt
948    ) => {
949        $crate::__resolve_finish! {
950            on_finish $finish
951            output {
952                consumed_bounds $parsed_bounds
953                rest $rest
954            }
955        }
956    };
957    // an outer >
958    (
959        $parsed_bounds:tt
960        {> $($after:tt)*}
961        $rest:tt
962        $finish:tt
963    ) => {
964        $crate::__resolve_finish! {
965            on_finish $finish
966            output {
967                consumed_bounds $parsed_bounds
968                rest $rest
969            }
970        }
971    };
972    // an outer >=
973    (
974        $parsed_bounds:tt
975        {>= $($after:tt)*}
976        $rest:tt
977        $finish:tt
978    ) => {
979        $crate::__resolve_finish! {
980            on_finish $finish
981            output {
982                consumed_bounds $parsed_bounds
983                rest $rest
984            }
985        }
986    };
987    // an outer >>
988    (
989        $parsed_bounds:tt
990        {>> $($after:tt)*}
991        $rest:tt
992        $finish:tt
993    ) => {
994        $crate::__resolve_finish! {
995            on_finish $finish
996            output {
997                consumed_bounds $parsed_bounds
998                rest $rest
999            }
1000        }
1001    };
1002    // an outer >>=
1003    (
1004        $parsed_bounds:tt
1005        {>>= $($after:tt)*}
1006        $rest:tt
1007        $finish:tt
1008    ) => {
1009        $crate::__resolve_finish! {
1010            on_finish $finish
1011            output {
1012                consumed_bounds $parsed_bounds
1013                rest $rest
1014            }
1015        }
1016    };
1017    // an outer =>
1018    (
1019        {$($parsed_bounds:tt)*}
1020        {=> $($rest:tt)*}
1021        $_rest:tt
1022        $finish:tt
1023    ) => {
1024        $crate::__resolve_finish! {
1025            on_finish $finish
1026            output {
1027                consumed_bounds {$($parsed_bounds)* =} // split => into = and >
1028                rest {> $($rest)*}
1029            }
1030        }
1031    };
1032    // `<` , consume till a matched `>`
1033    (
1034        {$($parsed_bounds:tt)*}
1035        {<     $($_rest:tt)*}
1036        {$t:tt $($rest:tt )*}
1037        $finish:tt
1038    ) => {
1039        $crate::__impl_consume_till_outer_gt! {
1040            {$($parsed_bounds)* $t}
1041            {$($rest)*}
1042            {$($rest)*}
1043            []
1044            {
1045                on_finish { $crate::__impl_consume_bounds_on_finish_consume_till_gt! }
1046                append { finish $finish }
1047            }
1048        }
1049    };
1050    // `<=` , consume till a matched `>`
1051    (
1052        {$($parsed_bounds:tt)*}
1053        {<=    $($_rest:tt)*}
1054        {$t:tt $($rest:tt )*}
1055        $finish:tt
1056    ) => {
1057        $crate::__impl_consume_till_outer_gt! {
1058            {$($parsed_bounds)* $t}
1059            {$($rest)*}
1060            {$($rest)*}
1061            []
1062            {
1063                on_finish { $crate::__impl_consume_bounds_on_finish_consume_till_gt! }
1064                append { finish $finish }
1065            }
1066        }
1067    };
1068    // `<-` , consume till a matched `>`
1069    (
1070        {$($parsed_bounds:tt)*}
1071        {<-    $($_rest:tt)*}
1072        {$t:tt $($rest:tt )*}
1073        $finish:tt
1074    ) => {
1075        $crate::__impl_consume_till_outer_gt! {
1076            {$($parsed_bounds)* $t}
1077            {$($rest)*}
1078            {$($rest)*}
1079            []
1080            {
1081                on_finish { $crate::__impl_consume_bounds_on_finish_consume_till_gt! }
1082                append { finish $finish }
1083            }
1084        }
1085    };
1086    // `<<` , consume till two matched `>` `>`
1087    (
1088        {$($parsed_bounds:tt)*}
1089        {<<    $($_rest:tt)*}
1090        {$t:tt $($rest:tt )*}
1091        $finish:tt
1092    ) => {
1093        $crate::__impl_consume_till_outer_gt! {
1094            {$($parsed_bounds)* $t}
1095            {$($rest)*}
1096            {$($rest)*}
1097            [<]
1098            {
1099                on_finish { $crate::__impl_consume_bounds_on_finish_consume_till_gt! }
1100                append { finish $finish }
1101            }
1102        }
1103    };
1104    // `<<=` , consume till two matched `>` `>`
1105    (
1106        {$($parsed_bounds:tt)*}
1107        {<<=   $($_rest:tt)*}
1108        {$t:tt $($rest:tt )*}
1109        $finish:tt
1110    ) => {
1111        $crate::__impl_consume_till_outer_gt! {
1112            {$($parsed_bounds)* $t}
1113            {$($rest)*}
1114            {$($rest)*}
1115            [<]
1116            {
1117                on_finish { $crate::__impl_consume_bounds_on_finish_consume_till_gt! }
1118                append { finish $finish }
1119            }
1120        }
1121    };
1122    // other cases, just consume
1123    (
1124        {$($parsed_bounds:tt)*}
1125        {$t:tt $($rest:tt)*}
1126        $t_and_rest:tt
1127        $finish:tt
1128    ) => {
1129        $crate::__impl_consume_bounds! {
1130            {$($parsed_bounds)* $t}
1131            {$($rest)*}
1132            {$($rest)*}
1133            $finish
1134        }
1135    };
1136}
1137
1138#[doc(hidden)]
1139#[macro_export]
1140macro_rules! __impl_consume_bounds_on_finish_consume_till_gt {
1141    (
1142        before_gt $before_gt:tt
1143        gt_and_rest $gt_and_rest:tt
1144        finish $finish:tt
1145    ) => {
1146        // continue parse bounds
1147        $crate::__impl_split_gt_and_rest! {
1148            $gt_and_rest
1149            $gt_and_rest
1150            {
1151                on_finish {$crate::__impl_consume_bounds_consume_first_gt_and_continue!}
1152                prepend {
1153                    finish $finish
1154                    before_gt $before_gt
1155                }
1156            }
1157        }
1158    };
1159}
1160
1161#[doc(hidden)]
1162#[macro_export]
1163macro_rules! __impl_consume_bounds_consume_first_gt_and_continue {
1164    (
1165        finish $finish:tt
1166        before_gt { $($before_gt:tt)* }
1167        gt {$gt:tt}
1168        rest $rest:tt
1169    ) => {
1170        $crate::__impl_consume_bounds! {
1171            {$($before_gt)* $gt}
1172            $rest
1173            $rest
1174            $finish
1175        }
1176    };
1177}
1178
1179// endregion
1180
1181// region: consume_optional_angle_bracketed
1182
1183#[macro_export]
1184macro_rules! consume_optional_angle_bracketed {
1185    ($($args:tt)*) => {
1186        $crate::__start_parsing_with! {
1187            parse_with { $crate::__impl_consume_optional_angle_bracketed_start! }
1188            args {
1189                $($args)*
1190            }
1191        }
1192    };
1193}
1194
1195#[doc(hidden)]
1196#[macro_export]
1197macro_rules! __impl_consume_optional_angle_bracketed_start {
1198    (
1199        {}
1200        {<      $($_rest:tt)*}
1201        {$lt:tt $($rest:tt )*}
1202        $finish:tt
1203    ) => {
1204        $crate::__impl_consume_till_outer_gt_inclusive! {
1205            {$lt}
1206            {$($rest)*}
1207            {$($rest)*}
1208            []
1209            {
1210                on_finish {$crate::__impl_consume_optional_angle_bracketed_finish!}
1211                prepend { on_finish $finish }
1212            }
1213        }
1214    };
1215    (
1216        {}
1217        {<-    $($_rest:tt)*}
1218        {$t:tt $($rest:tt )*}
1219        $finish:tt
1220    ) => {
1221        $crate::__impl_consume_till_outer_gt_inclusive! {
1222            {$t}
1223            {$($rest)*}
1224            {$($rest)*}
1225            []
1226            {
1227                on_finish {$crate::__impl_consume_optional_angle_bracketed_finish!}
1228                prepend { on_finish $finish }
1229            }
1230        }
1231    };
1232    (
1233        {}
1234        {<=    $($_rest:tt)*}
1235        {$t:tt $($rest:tt )*}
1236        $finish:tt
1237    ) => {
1238        $crate::__impl_consume_till_outer_gt_inclusive! {
1239            {$t}
1240            {$($rest)*}
1241            {$($rest)*}
1242            []
1243            {
1244                on_finish {$crate::__impl_consume_optional_angle_bracketed_finish!}
1245                prepend { on_finish $finish }
1246            }
1247        }
1248    };
1249    (
1250        {}
1251        {<<    $($_rest:tt)*}
1252        {$t:tt $($rest:tt )*}
1253        $finish:tt
1254    ) => {
1255        $crate::__impl_consume_till_outer_gt_inclusive! {
1256            {$t}
1257            {$($rest)*}
1258            {$($rest)*}
1259            [<] // one inner <
1260            {
1261                on_finish {$crate::__impl_consume_optional_angle_bracketed_finish!}
1262                prepend { on_finish $finish }
1263            }
1264        }
1265    };
1266    (
1267        {}
1268        {<<=   $($_rest:tt)*}
1269        {$t:tt $($rest:tt )*}
1270        $finish:tt
1271    ) => {
1272        $crate::__impl_consume_till_outer_gt_inclusive! {
1273            {$t}
1274            {$($rest)*}
1275            {$($rest)*}
1276            [<] // one inner <
1277            {
1278                on_finish {$crate::__impl_consume_optional_angle_bracketed_finish!}
1279                prepend { on_finish $finish }
1280            }
1281        }
1282    };
1283    // no leading <
1284    (
1285        {}
1286        $rest:tt
1287        $_rest:tt
1288        $finish:tt
1289    ) => {
1290        $crate::__resolve_finish! {
1291            on_finish $finish
1292            output {
1293                // angle_bracketed $before_and_gt
1294                rest $rest
1295            }
1296        }
1297    };
1298}
1299
1300#[doc(hidden)]
1301#[macro_export]
1302macro_rules! __impl_consume_optional_angle_bracketed_finish {
1303    (
1304        on_finish $finish:tt
1305        before_and_gt $before_and_gt:tt
1306        after_gt $after_gt:tt
1307    ) => {
1308        $crate::__resolve_finish! {
1309            on_finish $finish
1310            output {
1311                angle_bracketed $before_and_gt
1312                rest $after_gt
1313            }
1314        }
1315    };
1316}
1317
1318// endregion
1319
1320// region: parse_generics
1321
1322/// Parse generics
1323///
1324/// Input should be zero or many generics separated by `,` with an optional trailing `,` and
1325/// end with `EOF` or `>`.
1326///
1327/// ```
1328/// macro_rules! expect_output {
1329///     (
1330///         parsed_generics {
1331///             generics {$($generics:tt)*} // the original generics with a trailing comma
1332///             impl_generics {$($impl_generics:tt)*} // generics with a trailing comma but without default types and default exprs
1333///             type_generics {$($type_generics:tt)*} // generics with a trailing comma that can be used as type parameters of a generic path
1334///             generics_info {$($generics_info:tt)*} // info of all generics
1335///         }
1336///         rest { > }
1337///     ) => {
1338///         // ..
1339///     };
1340/// }
1341///
1342/// syn_lite::parse_generics! {
1343///     on_finish { expect_output! }
1344///     input { 'a, 'b: 'c, T: ?Sized + FnOnce(), > }
1345/// }
1346/// ```
1347///
1348/// Here is a full example:
1349///
1350/// ```
1351/// # let res = syn_lite::parse_generics! { on_finish { full_output! }
1352/// input {
1353///     /// lifetime
1354///     'a: 'b + 'c,
1355///     /// type param
1356///     T: FnOnce() -> u8 + 'static + ?Sized = dyn FnOnce() -> u8,
1357///     /// const
1358///     const N: &'static str = "default expr"
1359/// }
1360/// # };
1361/// # assert_eq!(res, ("dyn FnOnce() -> u8", "&'static str", "default expr"));
1362/// /// output
1363/// # #[macro_export] macro_rules! full_output {(
1364/// parsed_generics {
1365///     // the original generics with a trailing comma
1366///     generics      { #[doc = r" lifetime"] 'a: 'b + 'c, #[doc = r" type param"] T: FnOnce() -> u8 + 'static + ?Sized = $DefaultType:ty, #[doc = r" const"] const N: $ConstType:ty = $const_default_expr:expr, }
1367///     // generics with a trailing comma but without default types and default exprs
1368///     impl_generics { #[doc = r" lifetime"] 'a: 'b + 'c, #[doc = r" type param"] T: FnOnce() -> u8 + 'static + ?Sized                  , #[doc = r" const"] const N: $ConstTyp_:ty                           , }
1369///     // generics with a trailing comma that can be used as type parameters of a generic path
1370///     type_generics { #[doc = r" lifetime"] 'a         , #[doc = r" type param"] T                                                     , #[doc = r" const"]       N                                          , }
1371///     // info of all generics
1372///     generics_info {
1373///         {
1374///             lifetime_attrs {#[doc = r" lifetime"]} // present if there are attributes
1375///             lifetime { 'a }
1376///             bounds { 'b + 'c } // present if there is a colon. This might be empty
1377///         }
1378///         {
1379///             type_attrs {#[doc = r" type param"]} // present if there are attributes
1380///             name { T }
1381///             bounds { FnOnce() -> u8 + 'static + ?Sized } // present if there is a colon. This might be empty
1382///             default_ty { $DefaultTypeOfT:ty } // present if there is a `= $default_ty:ty`
1383///         }
1384///         {
1385///             const_attrs {#[doc = r" const"]} // present if there are attributes
1386///             const { const }
1387///             name { N }
1388///             bounds { $TypeOfN:ty }
1389///             default_expr { $DefaultExprOfN:expr } // present if there is a `= $default_expr:expr`
1390///         }
1391///     }
1392/// }
1393/// rest {}
1394/// # )=>{{
1395/// # assert_eq!(stringify!($ConstType), stringify!($ConstTyp_));
1396/// # assert_eq!(stringify!($DefaultType), stringify!($DefaultTypeOfT));
1397/// # assert_eq!(stringify!($DefaultExprOfN), stringify!($DefaultExprOfN));
1398/// # (stringify!($DefaultType), stringify!($ConstType), $const_default_expr)
1399/// # }}}
1400/// ```
1401#[macro_export]
1402macro_rules! parse_generics {
1403    ($($args:tt)*) => {
1404        $crate::__start_parsing_with! {
1405            parse_with { $crate::__parse_generics_start! }
1406            args {
1407                $($args)*
1408            }
1409        }
1410    };
1411}
1412
1413#[doc(hidden)]
1414#[macro_export]
1415macro_rules! __parse_generics_start {
1416    (
1417        {}
1418        $($rest:tt)*
1419    ) => {
1420        $crate::__parse_generics! {
1421            {
1422                generics {}
1423                impl_generics {}
1424                type_generics {}
1425                generics_info {}
1426            }
1427            $($rest)*
1428        }
1429    };
1430}
1431
1432#[doc(hidden)]
1433#[macro_export]
1434macro_rules! __parse_generics {
1435    // EOF
1436    (
1437        $parsed_generics:tt
1438        {}
1439        {}
1440        $finish:tt
1441    ) => {
1442        $crate::__resolve_finish! {
1443            on_finish $finish
1444            output {
1445                parsed_generics $parsed_generics
1446                rest {}
1447            }
1448        }
1449    };
1450    // >
1451    (
1452        $parsed_generics:tt
1453        { >      $($_rest:tt)* }
1454        $rest:tt
1455        $finish:tt
1456    ) => {
1457        $crate::__resolve_finish! {
1458            on_finish $finish
1459            output {
1460                parsed_generics $parsed_generics
1461                rest $rest
1462            }
1463        }
1464    };
1465    // >>
1466    (
1467        $parsed_generics:tt
1468        { >>    $($_rest:tt)* }
1469        $rest:tt
1470        $finish:tt
1471    ) => {
1472        $crate::__resolve_finish! {
1473            on_finish $finish
1474            output {
1475                parsed_generics $parsed_generics
1476                rest $rest
1477            }
1478        }
1479    };
1480    // >=
1481    (
1482        $parsed_generics:tt
1483        { >=    $($_rest:tt)* }
1484        $rest:tt
1485        $finish:tt
1486    ) => {
1487        $crate::__resolve_finish! {
1488            on_finish $finish
1489            output {
1490                parsed_generics $parsed_generics
1491                rest $rest
1492            }
1493        }
1494    };
1495    // >>=
1496    (
1497        $parsed_generics:tt
1498        { >>=    $($_rest:tt)* }
1499        $rest:tt
1500        $finish:tt
1501    ) => {
1502        $crate::__resolve_finish! {
1503            on_finish $finish
1504            output {
1505                parsed_generics $parsed_generics
1506                rest $rest
1507            }
1508        }
1509    };
1510    // 'a:
1511    (
1512        $parsed:tt
1513        { $(#[$($_attr:tt)*])* $_lt:lifetime :         $($_bounds_and_rest:tt)* }
1514        { $(#$attr:tt       )* $lt:lifetime  $colon:tt $($bounds_and_rest:tt )* }
1515        $finish:tt
1516    ) => {
1517        $crate::__impl_consume_bounds! {
1518            {}
1519            {$($bounds_and_rest)*}
1520            {$($bounds_and_rest)*}
1521            {
1522                on_finish { $crate::__parse_generics_lifetime_process_consumed_bounds! }
1523                prepend {
1524                    parsed_generics $parsed
1525                    generic_and_colon {
1526                        attrs { $(#$attr)* }
1527                        $lt $colon
1528                    }
1529                }
1530                append {
1531                    finish $finish
1532                }
1533            }
1534        }
1535    };
1536    // 'a
1537    (
1538        {
1539            generics { $($generics:tt)* }
1540            impl_generics { $($impl_generics:tt)* }
1541            type_generics { $($type_generics:tt)* }
1542            generics_info { $($generics_info:tt)* }
1543        }
1544        { $($(#[$($_attr:tt)*])+)? $_lt:lifetime $($_rest:tt)* }
1545        { $($(#$attr:tt       )+)? $lt:lifetime  $($rest:tt )* }
1546        $finish:tt
1547    ) => {
1548        $crate::__parse_generics_match_one_of_comma_gt_eof! {
1549            // trailing comma is added later
1550            {
1551                generics      { $($generics)*      $($(#$attr)+)? $lt }
1552                impl_generics { $($impl_generics)* $($(#$attr)+)? $lt }
1553                type_generics { $($type_generics)* $($(#$attr)+)? $lt }
1554                generics_info {
1555                    $($generics_info)*
1556                    {
1557                        $( lifetime_attrs {$(#$attr)+} )?
1558                        lifetime {$lt}
1559                    }
1560                }
1561            }
1562            {$($rest)*}
1563            {$($rest)*}
1564            $finish
1565        }
1566    };
1567    // `const N: usize =`
1568    (
1569        $parsed_generics:tt
1570        { $(#[$($_attr:tt)*])* const        $_name:ident :         $_bounds:ty = $($_default_expr_and_rest:tt)* }
1571        { $(#$attr:tt       )* $const:ident $name:ident  $colon:tt $bounds:ty  = $($default_expr_and_rest:tt )* }
1572        $finish:tt
1573    ) => {
1574        $crate::__parse_generics_match_default_expr! {
1575            {
1576                parsed_generics $parsed_generics
1577                generic {
1578                    attrs {$(#$attr)*}
1579                    $const $name
1580                }
1581                colon {$colon}
1582                ty {$bounds}
1583                eq {=}
1584            }
1585            {$($default_expr_and_rest)*}
1586            {$($default_expr_and_rest)*}
1587            $finish
1588        }
1589    };
1590    // `const N: usize,` or `const N: usize EOF`
1591    (
1592        {
1593            generics { $($generics:tt)* }
1594            impl_generics { $($impl_generics:tt)* }
1595            type_generics { $($type_generics:tt)* }
1596            generics_info { $($generics_info:tt)* }
1597        }
1598        { $($(#[$($_attr:tt)*])+)? const        $_name:ident :         $_bounds:ty $(, $($_rest:tt)*)? }
1599        { $($(#$attr:tt       )+)? $const:ident $name:ident  $colon:tt $bounds:ty  $(, $($rest:tt )*)? }
1600        $finish:tt
1601    ) => {
1602        $crate::__parse_generics! {
1603            {
1604                generics      { $($generics)*      $($(#$attr)+)? $const $name $colon $bounds , }
1605                impl_generics { $($impl_generics)* $($(#$attr)+)? $const $name $colon $bounds , }
1606                type_generics { $($type_generics)* $($(#$attr)+)?        $name                , }
1607                generics_info {
1608                    $($generics_info)*
1609                    {
1610                        $(const_attrs {$(#$attr)+})?
1611                        const {$const}
1612                        name {$name}
1613                        bounds {$bounds}
1614                    }
1615                }
1616            }
1617            {$($($rest)*)?}
1618            {$($($rest)*)?}
1619            $finish
1620        }
1621    };
1622    // `const N: usize >`
1623    (
1624        {
1625            generics { $($generics:tt)* }
1626            impl_generics { $($impl_generics:tt)* }
1627            type_generics { $($type_generics:tt)* }
1628            generics_info { $($generics_info:tt)* }
1629        }
1630        { $($(#[$($_attr:tt)*])+)? const        $_name:ident :         $_bounds:ty > $($_rest:tt)* }
1631        { $($(#$attr:tt       )+)? $const:ident $name:ident  $colon:tt $bounds:ty  > $($rest:tt )* }
1632        $finish:tt
1633    ) => {
1634        $crate::__resolve_finish! {
1635            on_finish $finish
1636            output {
1637                parsed_generics {
1638                    generics      { $($generics)*      $($(#$attr)+)? $const $name $colon $bounds , }
1639                    impl_generics { $($impl_generics)* $($(#$attr)+)? $const $name $colon $bounds , }
1640                    type_generics { $($type_generics)* $($(#$attr)+)?        $name                  }
1641                    generics_info {
1642                        $($generics_info)*
1643                        {
1644                            $(const_attrs {$(#$attr)+})?
1645                            const {$const}
1646                            name {$name}
1647                            bounds {$bounds}
1648                        }
1649                    }
1650                }
1651                rest { > $($rest)* }
1652            }
1653        }
1654    };
1655    // `const N: usize >>`
1656    (
1657        {
1658            generics { $($generics:tt)* }
1659            impl_generics { $($impl_generics:tt)* }
1660            type_generics { $($type_generics:tt)* }
1661            generics_info { $($generics_info:tt)* }
1662        }
1663        { $($(#[$($_attr:tt)*])+)? const        $_name:ident :         $_bounds:ty >> $($_rest:tt)* }
1664        { $($(#$attr:tt       )+)? $const:ident $name:ident  $colon:tt $bounds:ty  >> $($rest:tt )* }
1665        $finish:tt
1666    ) => {
1667        $crate::__resolve_finish! {
1668            on_finish $finish
1669            output {
1670                parsed_generics {
1671                    generics      { $($generics)*      $($(#$attr)+)? $const $name $colon $bounds , }
1672                    impl_generics { $($impl_generics)* $($(#$attr)+)? $const $name $colon $bounds , }
1673                    type_generics { $($type_generics)* $($(#$attr)+)?        $name                  }
1674                    generics_info {
1675                        $($generics_info)*
1676                        {
1677                            $(const_attrs {$(#$attr)+})?
1678                            const {$const}
1679                            name {$name}
1680                            bounds {$bounds}
1681                        }
1682                    }
1683                }
1684                rest { >> $($rest)* }
1685            }
1686        }
1687    };
1688    // T:
1689    (
1690        $parsed:tt
1691        { $(#[$($_attr:tt)*])* $_name:ident :         $($_bounds_and_rest:tt)* }
1692        { $(#$attr:tt       )* $name:ident  $colon:tt $($bounds_and_rest:tt )* }
1693        $finish:tt
1694    ) => {
1695        $crate::__impl_consume_bounds! {
1696            {}
1697            {$($bounds_and_rest)*}
1698            {$($bounds_and_rest)*}
1699            {
1700                on_finish { $crate::__parse_generics_type_process_consumed_bounds! }
1701                prepend {
1702                    parsed_generics $parsed
1703                    generic { attrs {$(#$attr)*} $name }
1704                    colon { $colon }
1705                }
1706                append {
1707                    finish $finish
1708                }
1709            }
1710        }
1711    };
1712    // T
1713    (
1714        $parsed_generics:tt
1715        { $(#[$($_attr:tt)*])* $_name:ident $($_rest:tt)* }
1716        { $(#$attr:tt       )* $name:ident  $($rest:tt )* }
1717        $finish:tt
1718    ) => {
1719        $crate::__parse_generics_after_type_parse_bounds! {
1720            parsed_generics $parsed_generics
1721            generic { attrs {$(#$attr)*} $name }
1722            rest {$($rest)*} {$($rest)*}
1723            finish $finish
1724        }
1725    };
1726}
1727
1728#[doc(hidden)]
1729#[macro_export]
1730macro_rules! __parse_generics_lifetime_process_consumed_bounds {
1731    (
1732        parsed_generics {
1733            generics { $($generics:tt)* }
1734            impl_generics { $($impl_generics:tt)* }
1735            type_generics { $($type_generics:tt)* }
1736            generics_info { $($generics_info:tt)* }
1737        }
1738        generic_and_colon {
1739            attrs {$($($attrs:tt)+)?}
1740            $lt:lifetime $colon:tt
1741        }
1742        consumed_bounds {$($parsed_bounds:tt)*}
1743        rest $rest:tt
1744        finish $finish:tt
1745    ) => {
1746        $crate::__parse_generics_match_one_of_comma_gt_eof! {
1747            // trailing comma is added later
1748            {
1749                generics      { $($generics)*      $($($attrs)+)? $lt $colon $($parsed_bounds)* }
1750                impl_generics { $($impl_generics)* $($($attrs)+)? $lt $colon $($parsed_bounds)* }
1751                type_generics { $($type_generics)* $($($attrs)+)? $lt                           }
1752                generics_info {
1753                    $($generics_info)*
1754                    {
1755                        $( lifetime_attrs {$($attrs)+} )?
1756                        lifetime {$lt}
1757                        bounds {$($parsed_bounds)*}
1758                    }
1759                }
1760            }
1761            $rest $rest
1762            $finish
1763        }
1764    };
1765}
1766
1767#[doc(hidden)]
1768#[macro_export]
1769macro_rules! __parse_generics_type_process_consumed_bounds {
1770    (
1771        parsed_generics $parsed_generics:tt
1772        generic $generic:tt
1773        colon $colon:tt
1774        consumed_bounds $parsed_bounds:tt
1775        rest $rest:tt
1776        finish $finish:tt
1777    ) => {
1778        $crate::__parse_generics_after_type_parse_bounds! {
1779            parsed_generics $parsed_generics
1780            generic $generic
1781            colon $colon
1782            parsed_bounds $parsed_bounds
1783            rest $rest $rest
1784            finish $finish
1785        }
1786    };
1787}
1788
1789// without trailing comma
1790#[doc(hidden)]
1791#[macro_export]
1792macro_rules! __parse_generics_match_one_of_comma_gt_eof {
1793    // eof
1794    (
1795        $parsed_generics:tt
1796        {} $rest:tt
1797        $finish:tt
1798    ) => {
1799        $crate::__parse_generics_append_trailing_comma! {
1800            $parsed_generics
1801            ,
1802            {
1803                on_finish { $crate::__parse_generics_end! }
1804                append {
1805                    $rest
1806                    $finish
1807                }
1808            }
1809        }
1810    };
1811    // ,
1812    (
1813        $parsed_generics:tt
1814        {,         $($_rest:tt)*}
1815        {$comma:tt $($rest:tt )*}
1816        $finish:tt
1817    ) => {
1818        $crate::__parse_generics_append_trailing_comma! {
1819            $parsed_generics
1820            $comma
1821            {
1822                on_finish { $crate::__parse_generics! }
1823                append {
1824                    {$($rest)*}
1825                    {$($rest)*}
1826                    $finish
1827                }
1828            }
1829        }
1830    };
1831    // >
1832    (
1833        $parsed_generics:tt
1834        {> $($_rest:tt)*}
1835        $rest:tt
1836        $finish:tt
1837    ) => {
1838        $crate::__parse_generics_append_trailing_comma! {
1839            $parsed_generics
1840            ,
1841            {
1842                on_finish { $crate::__parse_generics_end! }
1843                append {
1844                    $rest
1845                    $finish
1846                }
1847            }
1848        }
1849    };
1850    // >=
1851    (
1852        $parsed_generics:tt
1853        {>= $($_rest:tt)*}
1854        $rest:tt
1855        $finish:tt
1856    ) => {
1857        $crate::__parse_generics_append_trailing_comma! {
1858            $parsed_generics
1859            ,
1860            {
1861                on_finish { $crate::__parse_generics_end! }
1862                append {
1863                    $rest
1864                    $finish
1865                }
1866            }
1867        }
1868    };
1869    // >>
1870    (
1871        $parsed_generics:tt
1872        {>> $($_rest:tt)*}
1873        $rest:tt
1874        $finish:tt
1875    ) => {
1876        $crate::__parse_generics_append_trailing_comma! {
1877            $parsed_generics
1878            ,
1879            {
1880                on_finish { $crate::__parse_generics_end! }
1881                append {
1882                    $rest
1883                    $finish
1884                }
1885            }
1886        }
1887    };
1888    // >>=
1889    (
1890        parsed_generics $parsed_generics:tt
1891        {>>= $($_rest:tt)*}
1892        $rest:tt
1893        $finish:tt
1894    ) => {
1895        $crate::__parse_generics_append_trailing_comma! {
1896            $parsed_generics
1897            ,
1898            {
1899                on_finish { $crate::__parse_generics_end! }
1900                append {
1901                    $rest
1902                    $finish
1903                }
1904            }
1905        }
1906    };
1907}
1908
1909#[doc(hidden)]
1910#[macro_export]
1911macro_rules! __parse_generics_append_trailing_comma {
1912    (
1913        {
1914            generics { $($generics:tt)* }
1915            impl_generics { $($impl_generics:tt)* }
1916            type_generics { $($type_generics:tt)* }
1917            generics_info $generics_info:tt
1918        }
1919        $comma:tt
1920        $finish:tt
1921    ) => {
1922        $crate::__resolve_finish! {
1923            on_finish $finish
1924            output {
1925                {
1926                    generics { $($generics)* $comma }
1927                    impl_generics { $($impl_generics)* $comma }
1928                    type_generics { $($type_generics)* $comma }
1929                    generics_info $generics_info
1930                }
1931            }
1932        }
1933    };
1934}
1935
1936#[doc(hidden)]
1937#[macro_export]
1938macro_rules! __parse_generics_end {
1939    (
1940        $parsed_generics:tt
1941        $rest:tt
1942        $finish:tt
1943    ) => {
1944        $crate::__resolve_finish! {
1945            on_finish $finish
1946            output {
1947                parsed_generics $parsed_generics
1948                rest $rest
1949            }
1950        }
1951    };
1952}
1953
1954#[doc(hidden)]
1955#[macro_export]
1956macro_rules! __parse_generics_after_type_parse_bounds {
1957    (
1958        parsed_generics $parsed_generics:tt
1959        generic $generic:tt
1960        $(
1961            colon $colon:tt
1962            parsed_bounds $parsed_bounds:tt
1963        )?
1964        rest
1965        {=      $($_rest:tt)*}
1966        {$eq:tt $($rest:tt )*}
1967        finish $finish:tt
1968    ) => {
1969        $crate::__parse_generics_match_default_type! {
1970            {
1971                parsed_generics $parsed_generics
1972                generic $generic
1973                $(
1974                    colon $colon
1975                    parsed_bounds $parsed_bounds
1976                )?
1977                eq {$eq}
1978            }
1979            {$($rest)*}
1980            {$($rest)*}
1981            $finish
1982        }
1983    };
1984    (
1985        parsed_generics {
1986            generics { $($generics:tt)* }
1987            impl_generics { $($impl_generics:tt)* }
1988            type_generics { $($type_generics:tt)* }
1989            generics_info { $($generics_info:tt)* }
1990        }
1991        generic {
1992            attrs {$($($attrs:tt)+)?}
1993            $name:ident
1994        }
1995        $(
1996            colon {$colon:tt}
1997            parsed_bounds {$($parsed_bounds:tt)*}
1998        )?
1999        rest $rest:tt $_rest:tt
2000        finish $finish:tt
2001    ) => {
2002        $crate::__parse_generics_match_one_of_comma_gt_eof! {
2003            {
2004                generics      { $($generics)*      $($($attrs)+)? $name $($colon $($parsed_bounds)*)? }
2005                impl_generics { $($impl_generics)* $($($attrs)+)? $name $($colon $($parsed_bounds)*)? }
2006                type_generics { $($type_generics)* $($($attrs)+)? $name                               }
2007                generics_info {
2008                    $($generics_info)*
2009                    {
2010                        $(type_attrs { $($attrs)+ })?
2011                        name { $name }
2012                        $(bounds { $($parsed_bounds)* })?
2013                    }
2014                }
2015            }
2016            $rest
2017            $_rest
2018            $finish
2019        }
2020    };
2021}
2022
2023#[doc(hidden)]
2024#[macro_export]
2025macro_rules! __parse_generics_match_default_type {
2026    // ,
2027    (
2028        {
2029            parsed_generics {
2030                generics { $($generics:tt)* }
2031                impl_generics { $($impl_generics:tt)* }
2032                type_generics { $($type_generics:tt)* }
2033                generics_info { $($generics_info:tt)* }
2034            }
2035            generic {
2036                attrs {$($($attrs:tt)+)?}
2037                $name:ident
2038            }
2039            $(
2040                colon {$colon:tt}
2041                parsed_bounds { $($parsed_bounds:tt)* }
2042            )?
2043            eq {$eq:tt}
2044        }
2045        $_rest:tt
2046        {$ty:ty $(, $($rest:tt)* )?}
2047        $finish:tt
2048    ) => {
2049        $crate::__parse_generics! {
2050            {
2051                generics      { $($generics)*      $($($attrs)+)? $name $($colon $($parsed_bounds)*)? $eq $ty , }
2052                impl_generics { $($impl_generics)* $($($attrs)+)? $name $($colon $($parsed_bounds)*)?         , }
2053                type_generics { $($type_generics)* $($($attrs)+)? $name                                       , }
2054                generics_info {
2055                    $($generics_info)*
2056                    {
2057                        $(type_attrs { $($attrs)+ })?
2058                        name { $name }
2059                        $(bounds { $($parsed_bounds)* })?
2060                        default_ty { $ty }
2061                    }
2062                }
2063            }
2064            {$($($rest)*)?}
2065            {$($($rest)*)?}
2066            $finish
2067        }
2068    };
2069    // >
2070    (
2071        {
2072            parsed_generics {
2073                generics { $($generics:tt)* }
2074                impl_generics { $($impl_generics:tt)* }
2075                type_generics { $($type_generics:tt)* }
2076                generics_info { $($generics_info:tt)* }
2077            }
2078            generic {
2079                attrs {$($($attrs:tt)+)?}
2080                $name:ident
2081            }
2082            $(
2083                colon {$colon:tt}
2084                parsed_bounds { $($parsed_bounds:tt)* }
2085            )?
2086            eq {$eq:tt}
2087        }
2088        {$ty:ty > $($rest:tt)*}
2089        $_rest:tt
2090        $finish:tt
2091    ) => {
2092        $crate::__resolve_finish! {
2093            on_finish $finish
2094            output {
2095                parsed_generics {
2096                    generics      { $($generics)*      $($($attrs)+)? $name $($colon $($parsed_bounds)*)? $eq $ty , }
2097                    impl_generics { $($impl_generics)* $($($attrs)+)? $name $($colon $($parsed_bounds)*)?         , }
2098                    type_generics { $($type_generics)* $($($attrs)+)? $name                                       , }
2099                    generics_info {
2100                        $($generics_info)*
2101                        {
2102                            $(type_attrs { $($attrs)+ })?
2103                            name { $name }
2104                            $(bounds { $($parsed_bounds)* })?
2105                            default_ty { $ty }
2106                        }
2107                    }
2108                }
2109                rest {> $($rest)*}
2110            }
2111        }
2112    };
2113    // >>
2114    (
2115        {
2116            parsed_generics {
2117                generics { $($generics:tt)* }
2118                impl_generics { $($impl_generics:tt)* }
2119                type_generics { $($type_generics:tt)* }
2120                generics_info { $($generics_info:tt)* }
2121            }
2122            generic {
2123                attrs {$($($attrs:tt)+)?}
2124                $name:ident
2125            }
2126            $(
2127                colon {$colon:tt}
2128                parsed_bounds { $($parsed_bounds:tt)* }
2129            )?
2130            eq {$eq:tt}
2131        }
2132        {$ty:ty >> $($rest:tt)*}
2133        $_rest:tt
2134        $finish:tt
2135    ) => {
2136        $crate::__resolve_finish! {
2137            on_finish $finish
2138            output {
2139                parsed_generics {
2140                    generics      { $($generics)*      $($($attrs)+)? $name $($colon $($parsed_bounds)*)? $eq $ty , }
2141                    impl_generics { $($impl_generics)* $($($attrs)+)? $name $($colon $($parsed_bounds)*)?         , }
2142                    type_generics { $($type_generics)* $($($attrs)+)? $name                                       , }
2143                    generics_info {
2144                        $($generics_info)*
2145                        {
2146                            $(type_attrs { $($attrs)+ })?
2147                            name { $name }
2148                            $(bounds { $($parsed_bounds)* })?
2149                            default_ty { $ty }
2150                        }
2151                    }
2152                }
2153                rest {>> $($rest)*}
2154            }
2155        }
2156    };
2157}
2158
2159#[doc(hidden)]
2160#[macro_export]
2161macro_rules! __parse_generics_match_default_expr {
2162    // we cannot match $expr or `const N: usize = 1>` will be wrongly parsed
2163    // $path ,
2164    (
2165        {
2166            parsed_generics {
2167                generics { $($generics:tt)* }
2168                impl_generics { $($impl_generics:tt)* }
2169                type_generics { $($type_generics:tt)* }
2170                generics_info { $($generics_info:tt)* }
2171            }
2172            generic {
2173                attrs {$($($attrs:tt)+)?}
2174                $const:ident $name:ident
2175            }
2176            colon {$colon:tt}
2177            ty {$ty:ty}
2178            eq {$eq:tt}
2179        }
2180        $_rest:tt
2181        {$expr:path $(, $($rest:tt)* )?}
2182        $finish:tt
2183    ) => {
2184        $crate::__parse_generics! {
2185            {
2186                generics      { $($generics)*      $($($attrs)+)? $const $name $colon $ty $eq $expr , }
2187                impl_generics { $($impl_generics)* $($($attrs)+)? $const $name $colon $ty           , }
2188                type_generics { $($type_generics)* $($($attrs)+)?        $name                      , }
2189                generics_info {
2190                    $($generics_info)*
2191                    {
2192                        $(const_attrs { $($attrs)+ })?
2193                        const {$const}
2194                        name { $name }
2195                        bounds { $ty }
2196                        default_expr { $expr }
2197                    }
2198                }
2199            }
2200            {$($($rest)*)?}
2201            {$($($rest)*)?}
2202            $finish
2203        }
2204    };
2205    // $path >
2206    (
2207        {
2208            parsed_generics {
2209                generics { $($generics:tt)* }
2210                impl_generics { $($impl_generics:tt)* }
2211                type_generics { $($type_generics:tt)* }
2212                generics_info { $($generics_info:tt)* }
2213            }
2214            generic {
2215                attrs {$($($attrs:tt)+)?}
2216                $const:ident $name:ident
2217            }
2218            colon {$colon:tt}
2219            ty {$ty:ty}
2220            eq {$eq:tt}
2221        }
2222        $_rest:tt
2223        {$expr:path > $($rest:tt)*}
2224        $finish:tt
2225    ) => {
2226        $crate::__resolve_finish! {
2227            on_finish $finish
2228            output {
2229                parsed_generics {
2230                    generics      { $($generics)*      $($($attrs)+)? $const $name $colon $ty $eq $expr , }
2231                    impl_generics { $($impl_generics)* $($($attrs)+)? $const $name $colon $ty           , }
2232                    type_generics { $($type_generics)* $($($attrs)+)?        $name                      , }
2233                    generics_info {
2234                        $($generics_info)*
2235                        {
2236                            $(const_attrs { $($attrs)+ })?
2237                            const {$const}
2238                            name { $name }
2239                            bounds { $ty }
2240                            default_expr { $expr }
2241                        }
2242                    }
2243                }
2244                rest { > $($rest)* }
2245            }
2246        }
2247    };
2248    // $path >>
2249    (
2250        {
2251            parsed_generics {
2252                generics { $($generics:tt)* }
2253                impl_generics { $($impl_generics:tt)* }
2254                type_generics { $($type_generics:tt)* }
2255                generics_info { $($generics_info:tt)* }
2256            }
2257            generic {
2258                attrs {$($($attrs:tt)+)?}
2259                $const:ident $name:ident
2260            }
2261            colon {$colon:tt}
2262            ty {$ty:ty}
2263            eq {$eq:tt}
2264        }
2265        $_rest:tt
2266        {$expr:path >> $($rest:tt)*}
2267        $finish:tt
2268    ) => {
2269        $crate::__resolve_finish! {
2270            on_finish $finish
2271            output {
2272                parsed_generics {
2273                    generics      { $($generics)*      $($($attrs)+)? $const $name $colon $ty $eq $expr , }
2274                    impl_generics { $($impl_generics)* $($($attrs)+)? $const $name $colon $ty           , }
2275                    type_generics { $($type_generics)* $($($attrs)+)?        $name                      , }
2276                    generics_info {
2277                        $($generics_info)*
2278                        {
2279                            $(const_attrs { $($attrs)+ })?
2280                            const {$const}
2281                            name { $name }
2282                            bounds { $ty }
2283                            default_expr { $expr }
2284                        }
2285                    }
2286                }
2287                rest { >> $($rest)* }
2288            }
2289        }
2290    };
2291    // {..}
2292    (
2293        {
2294            parsed_generics {
2295                generics { $($generics:tt)* }
2296                impl_generics { $($impl_generics:tt)* }
2297                type_generics { $($type_generics:tt)* }
2298                generics_info { $($generics_info:tt)* }
2299            }
2300            generic {
2301                attrs {$($($attrs:tt)+)?}
2302                $const:ident $name:ident
2303            }
2304            colon {$colon:tt}
2305            ty {$ty:ty}
2306            eq {$eq:tt}
2307        }
2308        {{$($_expr:tt)*} $($_rest:tt)*}
2309        {$expr:tt        $($rest:tt )*}
2310        $finish:tt
2311    ) => {
2312        $crate::__parse_generics_match_one_of_comma_gt_eof! {
2313            {
2314                generics      { $($generics)*      $($($attrs)+)? $const $name $colon $ty $eq $expr }
2315                impl_generics { $($impl_generics)* $($($attrs)+)? $const $name $colon $ty           }
2316                type_generics { $($type_generics)* $($($attrs)+)?        $name                      }
2317                generics_info {
2318                    $($generics_info)*
2319                    {
2320                        $(const_attrs { $($attrs)+ })?
2321                        const {$const}
2322                        name { $name }
2323                        bounds { $ty }
2324                        default_expr { $expr }
2325                    }
2326                }
2327            }
2328            { $($rest)* }
2329            { $($rest)* }
2330            $finish
2331        }
2332    };
2333    // $literal
2334    (
2335        {
2336            parsed_generics {
2337                generics { $($generics:tt)* }
2338                impl_generics { $($impl_generics:tt)* }
2339                type_generics { $($type_generics:tt)* }
2340                generics_info { $($generics_info:tt)* }
2341            }
2342            generic {
2343                attrs {$($($attrs:tt)+)?}
2344                $const:ident $name:ident
2345            }
2346            colon {$colon:tt}
2347            ty {$ty:ty}
2348            eq {$eq:tt}
2349        }
2350        {$_expr:literal $($_rest:tt)*}
2351        {$expr:literal  $($rest:tt )*}
2352        $finish:tt
2353    ) => {
2354        $crate::__parse_generics_match_one_of_comma_gt_eof! {
2355            {
2356                generics      { $($generics)*      $($($attrs)+)? $const $name $colon $ty $eq $expr }
2357                impl_generics { $($impl_generics)* $($($attrs)+)? $const $name $colon $ty           }
2358                type_generics { $($type_generics)* $($($attrs)+)?        $name                      }
2359                generics_info {
2360                    $($generics_info)*
2361                    {
2362                        $(const_attrs { $($attrs)+ })?
2363                        const {$const}
2364                        name { $name }
2365                        bounds { $ty }
2366                        default_expr { $expr }
2367                    }
2368                }
2369            }
2370            { $($rest)* }
2371            { $($rest)* }
2372            $finish
2373        }
2374    };
2375}
2376
2377// endregion
2378
2379// region: parse_optional_angle_bracketed_generics
2380
2381/// Parse an optional angle bracketed generics `<'a, T, const N: usize>`
2382///
2383/// See also [`parse_generics!`].
2384///
2385/// ### Examples:
2386///
2387/// #### no angle bracketed generics
2388///
2389/// ```
2390/// macro_rules! expect_no_generics {
2391///     (rest { () -> u8 {} }) => {};
2392/// }
2393/// syn_lite::parse_optional_angle_bracketed_generics! {
2394///     on_finish {expect_no_generics!}
2395///     input { () -> u8 {} }
2396/// }
2397/// ```
2398///
2399/// #### empty generics
2400///
2401/// ```
2402/// macro_rules! expect {
2403///     (
2404///         lt {<}
2405///         parsed_generics {
2406///             generics {}
2407///             impl_generics {}
2408///             type_generics {}
2409///             generics_info {}
2410///         }
2411///         gt {>}
2412///         rest { () -> u8 {} }
2413///     ) => {};
2414/// }
2415/// syn_lite::parse_optional_angle_bracketed_generics! {
2416///     on_finish {expect!}
2417///     input { <>() -> u8 {} }
2418/// }
2419/// ```
2420///
2421/// #### lifetime generics
2422///
2423/// ```
2424/// macro_rules! expect {
2425///     (
2426///         lt {<}
2427///         parsed_generics {
2428///             generics {'a,}
2429///             impl_generics {'a,}
2430///             type_generics {'a,}
2431///             generics_info {
2432///                 { lifetime {'a} }
2433///             }
2434///         }
2435///         gt {>}
2436///         rest { () ->&'a str {} }
2437///     ) => {};
2438/// }
2439/// syn_lite::parse_optional_angle_bracketed_generics! {
2440///     on_finish {expect!}
2441///     input { <'a>() -> &'a str {} }
2442/// }
2443/// ```
2444#[macro_export]
2445macro_rules! parse_optional_angle_bracketed_generics {
2446    ($($args:tt)*) => {
2447        $crate::__start_parsing_with! {
2448            parse_with { $crate::__impl_parse_optional_angle_bracketed_generics_start! }
2449            args {
2450                $($args)*
2451            }
2452        }
2453    };
2454}
2455
2456#[doc(hidden)]
2457#[macro_export]
2458macro_rules! __impl_parse_optional_angle_bracketed_generics_start {
2459    // <>
2460    (
2461        {}
2462        {<      >      $($_rest:tt)*}
2463        {$lt:tt $gt:tt $($rest:tt)*}
2464        $finish:tt
2465    ) => {
2466        $crate::__resolve_finish! {
2467            on_finish $finish
2468            output {
2469                lt {$lt}
2470                parsed_generics {
2471                    generics {}
2472                    impl_generics {}
2473                    type_generics {}
2474                    generics_info {}
2475                }
2476                gt {$gt}
2477                rest { $($rest)* }
2478            }
2479        }
2480    };
2481    // <
2482    (
2483        {}
2484        {<      $($_rest:tt)*}
2485        {$lt:tt $($rest:tt)*}
2486        $finish:tt
2487    ) => {
2488        $crate::__parse_generics! {
2489            {
2490                generics {}
2491                impl_generics {}
2492                type_generics {}
2493                generics_info {}
2494            }
2495            {$($rest)*}
2496            {$($rest)*}
2497            {
2498                on_finish { $crate::__impl_parse_optional_angle_bracketed_generics_after_parse_generics! }
2499                prepend {
2500                    on_finish $finish
2501                    lt {$lt}
2502                }
2503            }
2504        }
2505    };
2506    // anything else
2507    (
2508        {}
2509        $_rest:tt
2510        $rest:tt
2511        $finish:tt
2512    ) => {
2513        $crate::__resolve_finish! {
2514            on_finish $finish
2515            output {
2516                rest $rest
2517            }
2518        }
2519    }
2520}
2521
2522#[doc(hidden)]
2523#[macro_export]
2524macro_rules! __impl_parse_optional_angle_bracketed_generics_after_parse_generics {
2525    (
2526        on_finish $finish:tt
2527        lt $lt:tt
2528        parsed_generics $parsed_generics:tt
2529        rest $rest:tt
2530    ) => {
2531        $crate::__impl_split_gt_and_rest! {
2532            $rest
2533            $rest
2534            {
2535                on_finish {$crate::__resolve_finish_flat!}
2536                prepend {
2537                    $finish
2538                    lt $lt
2539                    parsed_generics $parsed_generics
2540                }
2541            }
2542        }
2543    };
2544}
2545
2546// endregion
2547
2548// region: parse_item_fn
2549
2550/// Parse an item fn
2551///
2552/// Example:
2553///
2554/// ```
2555/// macro_rules! expect_item_fn {
2556///     (
2557///         item_fn {
2558///             $(outer_attrs { #[cfg(..)] })? // present if there are outer attributes
2559///             vis {$vis:tt}
2560///             sig {
2561///                                       // the following keywords are present if specified
2562///                 $(default {default})?
2563///                 $(const   {const}  )?
2564///                 $(async   {async}  )?
2565///                 $(unsafe  {unsafe} )?
2566///                 $(extern  {extern $($extern_name:literal)?})?
2567///
2568///                 fn { fn }
2569///                 ident { get }
2570///
2571///                 $(                                   // present if there is `<...>`
2572///                     lt {<}
2573///                     parsed_generics $parsed_generics:tt
2574///                     gt {>}
2575///                 )?
2576///
2577///                 paren_inputs { (self) }
2578///                 output { $(-> $output_ty:ty)? }
2579///
2580///                 $(                                      // present if there is where clause
2581///                     where_clause { where $($where_clause:tt)* }
2582///                 )?
2583///             }
2584///                                  // either block or semicolon will be present
2585///             $(block { {..} })?   // present if there is a block as fn body
2586///             $(semicolon { ; })?  // present if there is a semicolon
2587///         }
2588///         rest {}
2589///     ) => {};
2590/// }
2591///
2592/// syn_lite::parse_item_fn! {
2593///     on_finish { expect_item_fn! }
2594///     input {
2595///         #[cfg(..)]
2596///         fn get<T>(self) -> Option<T>
2597///         where
2598///             Self: Sized,
2599///         {
2600///             ..
2601///         }
2602///     }
2603/// }
2604/// ```
2605#[macro_export]
2606macro_rules! parse_item_fn {
2607    ($($args:tt)*) => {
2608        $crate::__start_parsing_with! {
2609            parse_with { $crate::__parse_item_fn_start! }
2610            args {
2611                $($args)*
2612            }
2613        }
2614    };
2615}
2616
2617#[doc(hidden)]
2618#[macro_export]
2619macro_rules! __parse_item_fn_start {
2620    (
2621        {}
2622        {
2623            $($(#$outer_attrs:tt)+)?
2624            $vis:vis
2625            $keyword:ident
2626            $($rest:tt)*
2627        }
2628        $_rest:tt
2629        $finish:tt
2630    ) => {
2631        $crate::__parse_item_fn_signature! {
2632            {}
2633            { $keyword $($rest)* }
2634            { $keyword $($rest)* }
2635            {
2636                on_finish {$crate::__parse_item_fn_after_sig!}
2637                prepend {
2638                    on_finish $finish
2639                    before_sig {
2640                        $(outer_attrs {$(#$outer_attrs)+})?
2641                        vis {$vis}
2642                    }
2643                }
2644            }
2645        }
2646    };
2647}
2648
2649#[doc(hidden)]
2650#[macro_export]
2651macro_rules! __parse_item_fn_after_sig {
2652    (
2653        on_finish $finish:tt
2654        before_sig {$($before_sig:tt)*}
2655        sig $sig:tt
2656        rest $rest:tt
2657    ) => {
2658        $crate::__parse_item_fn_block_or_semi! {
2659            $finish
2660            {
2661                $($before_sig)*
2662                sig $sig
2663            }
2664            $rest
2665            $rest
2666        }
2667    };
2668}
2669
2670#[doc(hidden)]
2671#[macro_export]
2672macro_rules! __parse_item_fn_block_or_semi {
2673    (
2674        $finish:tt
2675        {$($parsed_fn:tt)*}
2676        {;             $($_rest:tt)*}
2677        {$semicolon:tt $( $rest:tt)*}
2678    ) => {
2679        $crate::__resolve_finish! {
2680            on_finish $finish
2681            output {
2682                item_fn {
2683                    $($parsed_fn)*
2684                    semicolon {$semicolon}
2685                }
2686                rest {$($rest)*}
2687            }
2688        }
2689    };
2690    (
2691        $finish:tt
2692        {$($parsed_fn:tt)*}
2693        {{$($_block:tt)*} $($_rest:tt)*}
2694        {$block:tt        $( $rest:tt)*}
2695    ) => {
2696        $crate::__resolve_finish! {
2697            on_finish $finish
2698            output {
2699                item_fn {
2700                    $($parsed_fn)*
2701                    block {$block}
2702                }
2703                rest {$($rest)*}
2704            }
2705        }
2706    };
2707}
2708
2709// keyword order for functions declaration is `pub`, `default`, `const`, `async`, `unsafe`, `extern`
2710//
2711// this macro doesn't check the order
2712#[doc(hidden)]
2713#[macro_export]
2714macro_rules! __parse_item_fn_signature {
2715    (
2716        {$($parsed_sig:tt)*}
2717        { fn     $_ident:ident $($_rest:tt)*}
2718        { $fn:tt $ident:ident  $($rest:tt )*}
2719        $finish:tt
2720    ) => {
2721        $crate::__impl_parse_optional_angle_bracketed_generics_start! {
2722            {}
2723            {$($rest)*}
2724            {$($rest)*}
2725            {
2726                on_finish {$crate::__parse_item_fn_signature_process_abg!}
2727                prepend {
2728                    finish $finish
2729                    parsed_sig {
2730                        $($parsed_sig)*
2731                        fn {$fn}
2732                        ident {$ident}
2733                    }
2734                }
2735            }
2736        }
2737    };
2738    (
2739        {$($parsed_sig:tt)*}
2740        { default        $($_rest:tt)*}
2741        { $default:ident $($rest:tt )*}
2742        $finish:tt
2743    ) => {
2744        $crate::__parse_item_fn_signature! {
2745            { $($parsed_sig)* default {$default} }
2746            {$($rest)*}
2747            {$($rest)*}
2748            $finish
2749        }
2750    };
2751    (
2752        {$($parsed_sig:tt)*}
2753        { const        $($_rest:tt)*}
2754        { $const:ident $($rest:tt )*}
2755        $finish:tt
2756    ) => {
2757        $crate::__parse_item_fn_signature! {
2758            { $($parsed_sig)* const {$const} }
2759            {$($rest)*}
2760            {$($rest)*}
2761            $finish
2762        }
2763    };
2764    (
2765        {$($parsed_sig:tt)*}
2766        { async        $($_rest:tt)*}
2767        { $async:ident $($rest:tt )*}
2768        $finish:tt
2769    ) => {
2770        $crate::__parse_item_fn_signature! {
2771            { $($parsed_sig)* async {$async} }
2772            {$($rest)*}
2773            {$($rest)*}
2774            $finish
2775        }
2776    };
2777    (
2778        {$($parsed_sig:tt)*}
2779        { unsafe        $($_rest:tt)*}
2780        { $unsafe:ident $($rest:tt )*}
2781        $finish:tt
2782    ) => {
2783        $crate::__parse_item_fn_signature! {
2784            { $($parsed_sig)* unsafe {$unsafe} }
2785            {$($rest)*}
2786            {$($rest)*}
2787            $finish
2788        }
2789    };
2790    (
2791        {$($parsed_sig:tt)*}
2792        { extern        $($_name:literal)? $_other:ident $($_rest:tt)*}
2793        { $extern:ident $($name:literal )? $other:ident  $($rest:tt )*}
2794        $finish:tt
2795    ) => {
2796        $crate::__parse_item_fn_signature! {
2797            { $($parsed_sig)* extern {$extern $($name)?} }
2798            {$other $($rest)*}
2799            {$other $($rest)*}
2800            $finish
2801        }
2802    };
2803}
2804
2805#[doc(hidden)]
2806#[macro_export]
2807macro_rules! __parse_item_fn_signature_process_abg {
2808    (
2809        finish $finish:tt
2810        parsed_sig { $($parsed_sig:tt)* }
2811        $(
2812            lt $lt:tt
2813            parsed_generics $parsed_generics:tt
2814            gt $gt:tt
2815        )?
2816        rest $rest:tt
2817    ) => {
2818        $crate::__parse_item_fn_signature_after_generics! {
2819            $finish
2820            {
2821                $($parsed_sig)*
2822                $(
2823                    lt $lt
2824                    parsed_generics $parsed_generics
2825                    gt $gt
2826                )?
2827            }
2828            $rest $rest
2829        }
2830    };
2831}
2832
2833#[doc(hidden)]
2834#[macro_export]
2835macro_rules! __parse_item_fn_signature_after_generics {
2836    (
2837        $finish:tt
2838        { $($parsed_sig:tt)* }
2839        { ($($inputs:tt)*) ->        $($_output_ty_and_rest:tt)* }
2840        { $paren_inputs:tt $arrow:tt $($output_ty_and_rest:tt )* }
2841    ) => {
2842        $crate::__impl_consume_bounds! {
2843            { $arrow }
2844            { $($output_ty_and_rest)* }
2845            { $($output_ty_and_rest)* }
2846            {
2847                on_finish {$crate::__parse_item_fn_signature_process_consumed_bounds_as_type!}
2848                prepend {
2849                    on_finish $finish
2850                    parsed_sig {
2851                        $($parsed_sig)*
2852                        paren_inputs {$paren_inputs}
2853                    }
2854                }
2855            }
2856        }
2857    };
2858    (
2859        $finish:tt
2860        { $($parsed_sig:tt)* }
2861        { ($($inputs:tt)*) where     $($_where_predicates_and_rest:tt)*}
2862        { $paren_inputs:tt $where:tt $( $where_predicates_and_rest:tt)*}
2863    ) => {
2864        $crate::__consume_where_predicates! {
2865            {
2866                on_finish {$crate::__parse_item_fn_signature_process_consumed_where_predicates!}
2867                prepend {
2868                    finish $finish
2869                    parsed_sig {
2870                        $($parsed_sig)*
2871                        paren_inputs {$paren_inputs}
2872                        output {}
2873                    }
2874                }
2875            }
2876            {$where}
2877            {$($where_predicates_and_rest)*}
2878            {$($where_predicates_and_rest)*}
2879        }
2880    };
2881    (
2882        $finish:tt
2883        { $($parsed_sig:tt)* }
2884        { ($($inputs:tt)*)  $($_rest:tt)*}
2885        { $paren_inputs:tt  $( $rest:tt)*}
2886    ) => {
2887        $crate::__resolve_finish! {
2888            on_finish $finish
2889            output {
2890                sig {
2891                    $($parsed_sig)*
2892                    paren_inputs {$paren_inputs}
2893                    output {}
2894                }
2895                rest {$($rest)*}
2896            }
2897        }
2898    };
2899}
2900
2901#[doc(hidden)]
2902#[macro_export]
2903macro_rules! __parse_item_fn_signature_process_consumed_bounds_as_type {
2904    (
2905        on_finish $finish:tt
2906        parsed_sig {$($parsed_sig:tt)*}
2907        consumed_bounds $output:tt
2908        rest $rest:tt
2909    ) => {
2910        $crate::__parse_item_fn_signature_consume_optional_where_clause! {
2911            $finish
2912            { $($parsed_sig)* output $output }
2913            $rest
2914            $rest
2915        }
2916    };
2917}
2918
2919#[doc(hidden)]
2920#[macro_export]
2921macro_rules! __parse_item_fn_signature_consume_optional_where_clause {
2922    (
2923        $finish:tt
2924        $parsed_sig:tt
2925        { where     $($_where_predicates_and_rest:tt)* }
2926        { $where:tt $( $where_predicates_and_rest:tt)* }
2927    ) => {
2928        $crate::__consume_where_predicates! {
2929            {
2930                on_finish {$crate::__parse_item_fn_signature_process_consumed_where_predicates!}
2931                prepend {
2932                    finish $finish
2933                    parsed_sig $parsed_sig
2934                }
2935            }
2936            {$where}
2937            {$($where_predicates_and_rest)*}
2938            {$($where_predicates_and_rest)*}
2939        }
2940    };
2941    (
2942        $finish:tt
2943        $sig:tt
2944        $_rest:tt
2945        $rest:tt
2946    ) => {
2947        $crate::__resolve_finish! {
2948            on_finish $finish
2949            output {
2950                sig $sig
2951                rest $rest
2952            }
2953        }
2954    };
2955}
2956
2957#[doc(hidden)]
2958#[macro_export]
2959macro_rules! __parse_item_fn_signature_process_consumed_where_predicates {
2960    (
2961        finish $finish:tt
2962        parsed_sig { $($parsed_sig:tt)* }
2963        consumed $where_clause:tt
2964        rest $rest:tt
2965    ) => {
2966        $crate::__resolve_finish! {
2967            on_finish $finish
2968            output {
2969                sig {
2970                    $($parsed_sig)*
2971                    where_clause $where_clause
2972                }
2973                rest $rest
2974            }
2975        }
2976    };
2977}
2978
2979// endregion
2980
2981// region: consume_where_clause
2982
2983/// consume till one of the following tokens:
2984/// - EOF
2985/// - `;`
2986/// - `{..}`
2987#[doc(hidden)]
2988#[macro_export]
2989macro_rules! __consume_where_predicates {
2990    // EOF
2991    (
2992        $finish:tt
2993        $consumed:tt
2994        {}
2995        $rest:tt
2996    ) => {
2997        $crate::__resolve_finish! {
2998            on_finish $finish
2999            output {
3000                consumed $consumed
3001                rest $rest
3002            }
3003        }
3004    };
3005    // ;
3006    (
3007        $finish:tt
3008        $consumed:tt
3009        {; $($_rest:tt)*}
3010        $rest:tt
3011    ) => {
3012        $crate::__resolve_finish! {
3013            on_finish $finish
3014            output {
3015                consumed $consumed
3016                rest $rest
3017            }
3018        }
3019    };
3020    // {..}
3021    (
3022        $finish:tt
3023        $consumed:tt
3024        {{$($block:tt)*} $($_rest:tt)*}
3025        $rest:tt
3026    ) => {
3027        $crate::__resolve_finish! {
3028            on_finish $finish
3029            output {
3030                consumed $consumed
3031                rest $rest
3032            }
3033        }
3034    };
3035    // anything else
3036    (
3037        $finish:tt
3038        {$($consumed:tt)*}
3039        $_rest:tt
3040        {$t:tt $($rest:tt)*}
3041    ) => {
3042        $crate::__consume_where_predicates! {
3043            $finish
3044            {$($consumed)* $t}
3045            {$($rest)*}
3046            {$($rest)*}
3047        }
3048    };
3049}
3050
3051#[macro_export]
3052macro_rules! consume_optional_where_clause {
3053    ($($args:tt)*) => {
3054        $crate::__start_parsing_with_v2! {
3055            parse_with { $crate::__consume_optional_where_clause! }
3056            args {
3057                $($args)*
3058            }
3059        }
3060    };
3061}
3062
3063#[doc(hidden)]
3064#[macro_export]
3065macro_rules! __consume_optional_where_clause {
3066    (
3067        $on_finish_and_prepend:tt
3068        {where     $($_rest:tt)*}
3069        {$where:tt $( $rest:tt)*}
3070        $on_finish_append:tt
3071    ) => {
3072        $crate::__consume_where_predicates! {
3073            {
3074                on_finish {$crate::__consume_optional_where_clause_after_consume_where_predicates!}
3075                prepend { $on_finish_and_prepend }
3076                append { $on_finish_append }
3077            }
3078            {$where}
3079            {$($rest)*}
3080            {$($rest)*}
3081        }
3082    };
3083    (
3084        $on_finish_and_prepend:tt
3085        $_rest:tt
3086        $rest:tt
3087        $on_finish_append:tt
3088    ) => {
3089        $crate::__resolve_finish_v2! {
3090            $on_finish_and_prepend
3091            {
3092                rest $rest
3093            }
3094            $on_finish_append
3095        }
3096    };
3097}
3098
3099#[doc(hidden)]
3100#[macro_export]
3101macro_rules! __consume_optional_where_clause_after_consume_where_predicates {
3102    (
3103        $on_finish_and_prepend:tt
3104        consumed $where_clause:tt
3105        rest $rest:tt
3106        $on_finish_append:tt
3107    ) => {
3108        $crate::__resolve_finish_v2! {
3109            $on_finish_and_prepend
3110            {
3111                where_clause $where_clause
3112                rest $rest
3113            }
3114            $on_finish_append
3115        }
3116    };
3117}
3118
3119// endregion
3120
3121// region: consume_inner_attrs
3122
3123#[macro_export]
3124macro_rules! consume_inner_attrs {
3125    ($($args:tt)*) => {
3126        $crate::__start_parsing_with_v2! {
3127            parse_with { $crate::__consume_inner_attrs! }
3128            before_input {{}} // consumed
3129            args {
3130                $($args)*
3131            }
3132        }
3133    };
3134}
3135
3136#[doc(hidden)]
3137#[macro_export]
3138macro_rules! __consume_inner_attrs {
3139    (
3140        $on_finish_and_prepend:tt
3141        {$($parsed:tt)*}
3142        {#         !        [$($_attr1:tt)*] #         !        [$($_attr2:tt)*] $($_rest:tt)*}
3143        {$pound1:tt $bang1:tt $attr1:tt      $pound2:tt $bang2:tt $attr2:tt      $( $rest:tt)*}
3144        $on_finish_append:tt
3145    ) => {
3146        $crate::__consume_inner_attrs! {
3147            $on_finish_and_prepend
3148            {$($parsed)* $pound1 $bang1 $attr1 $pound2 $bang2 $attr2 }
3149            {$($rest)*}
3150            {$($rest)*}
3151            $on_finish_append
3152        }
3153    };
3154    (
3155        $on_finish_and_prepend:tt
3156        {$($parsed:tt)*}
3157        {#         !        [$($_attr:tt)*] $($_rest:tt)*}
3158        {$pound:tt $bang:tt $attr:tt        $( $rest:tt)*}
3159        $on_finish_append:tt
3160    ) => {
3161        $crate::__consume_inner_attrs! {
3162            $on_finish_and_prepend
3163            {$($parsed)* $pound $bang $attr}
3164            {$($rest)*}
3165            {$($rest)*}
3166            $on_finish_append
3167        }
3168    };
3169    (
3170        $on_finish_and_prepend:tt
3171        $consumed:tt
3172        $_rest:tt
3173        $rest:tt
3174        $on_finish_append:tt
3175    ) => {
3176        $crate::__resolve_finish_v2! {
3177            $on_finish_and_prepend
3178            {
3179                inner_attrs $consumed
3180                rest $rest
3181            }
3182            $on_finish_append
3183        }
3184    };
3185}
3186
3187// endregion