Skip to main content

macro_data/
lib.rs

1#[cfg(feature = "proc-macro")]
2mod proc_macro;
3
4#[cfg(feature = "proc-macro")]
5pub use proc_macro::*;
6
7/// This macro is used by other proc macros to transfer data.
8///
9/// It must be public to use it, but please don't call it directly.
10///
11/// Internal
12/// - The entry syntax is `macro_data_transfer!(<target-macro-path>, (<tokens>));`
13/// - Keep the result in `accu`, which is a list of tokentrees
14///     - Nested groups create a new tokentree to the left
15///     - Closing the group combines two tokentrees
16/// - Use `@load(<path>)` to call a macro and use the returned tokens
17///     - Other tokens are returned as is
18#[macro_export]
19macro_rules! macro_data_transfer {
20    // open ()
21    (
22        @normal,
23        $target:path,
24        ($accu:tt, $($accu_tail:tt,)*),
25        (($($arg:tt)*) $($arg_tail:tt)*),
26    ) => {
27        $crate::macro_data_transfer!(
28            @normal,
29            $target,
30            ((), $accu, $($accu_tail,)*),
31            ($($arg)* @close_param $($arg_tail)*),
32        );
33    };
34
35    // close ()
36    (
37        @normal,
38        $target:path,
39        (($($accu:tt)*), ($($accu_prev:tt)*), $($accu_tail:tt,)*),
40        (@close_param $($arg_tail:tt)*),
41    ) => {
42        $crate::macro_data_transfer!(
43            @normal,
44            $target,
45            (($($accu_prev)* ($($accu)*)), $($accu_tail,)*),
46            ($($arg_tail)*),
47        );
48    };
49
50    // open []
51    (
52        @normal,
53        $target:path,
54        ($accu:tt, $($accu_tail:tt,)*),
55        ([$($arg:tt)*] $($arg_tail:tt)*),
56    ) => {
57        $crate::macro_data_transfer!(
58            @normal,
59            $target,
60            ((), $accu, $($accu_tail,)*),
61            ($($arg)* @close_bracket $($arg_tail)*),
62        );
63    };
64
65    // close []
66    (
67        @normal,
68        $target:path,
69        (($($accu:tt)*), ($($accu_prev:tt)*), $($accu_tail:tt,)*),
70        (@close_bracket $($arg_tail:tt)*),
71    ) => {
72        $crate::macro_data_transfer!(
73            @normal,
74            $target,
75            (($($accu_prev)* [$($accu)*]), $($accu_tail,)*),
76            ($($arg_tail)*),
77        );
78    };
79
80    // open {}
81    (
82        @normal,
83        $target:path,
84        ($accu:tt, $($accu_tail:tt,)*),
85        ({$($arg:tt)*} $($arg_tail:tt)*),
86    ) => {
87        $crate::macro_data_transfer!(
88            @normal,
89            $target,
90            ((), $accu, $($accu_tail,)*),
91            ($($arg)* @close_braces $($arg_tail)*),
92        );
93    };
94
95    // close []
96    (
97        @normal,
98        $target:path,
99        (($($accu:tt)*), ($($accu_prev:tt)*), $($accu_tail:tt,)*),
100        (@close_braces $($arg_tail:tt)*),
101    ) => {
102        $crate::macro_data_transfer!(
103            @normal,
104            $target,
105            (($($accu_prev)* {$($accu)*}), $($accu_tail,)*),
106            ($($arg_tail)*),
107        );
108    };
109
110    // load data start
111    (
112        @normal,
113        $target:path,
114        $accu:tt,
115        (@load ($data:path) $($arg_tail:tt)*),
116    ) => {
117        $data!(
118            $crate::macro_data_transfer,
119            (
120                @ret,
121                $target,
122                $accu,
123                ($($arg_tail)*),
124            ),
125        );
126    };
127
128    // load data return
129    (
130        (
131            @ret,
132            $target:path,
133            (($($accu:tt)*), $($accu_tail:tt,)*),
134            $arg_tail:tt,
135        ),
136        ($($value:tt)*),
137    ) => {
138        $crate::macro_data_transfer!(
139            @normal,
140            $target,
141            (($($accu)* $($value)*), $($accu_tail,)*),
142            $arg_tail,
143        );
144    };
145
146    // any arg
147    (
148        @normal,
149        $target:path,
150        (($($accu:tt)*), $($accu_tail:tt,)*),
151        ($arg:tt $($arg_tail:tt)*),
152    ) => {
153        $crate::macro_data_transfer!(
154            @normal,
155            $target,
156            (($($accu)* $arg), $($accu_tail,)*),
157            ($($arg_tail)*),
158        );
159    };
160
161    // all parsed
162    (
163        @normal,
164        $target:path,
165        ($accu:tt,),
166        (),
167    ) => {
168        $target! $accu;
169    };
170
171    // public call
172    (
173        $target:path,
174        $arg:tt,
175    ) => {
176        $crate::macro_data_transfer!(
177            @normal,
178            $target,
179            ((),),
180            $arg,
181        );
182    };
183}