impls_index/implsindex/
impls.rs

1/// Define a private namespace for all its items.
2mod private
3{
4
5  /// Index of items.
6  #[ macro_export ]
7  macro_rules! index
8  {
9
10    () => { };
11
12    (
13      $Name : ident as $Alias : ident,
14      $( , $( $Rest : tt )* )?
15    )
16    =>
17    {
18      $Name!( as $Alias );
19      $crate::index!( $( $( $Rest )* )? );
20    };
21
22    (
23      $Name : ident
24      $( , $( $Rest : tt )* )?
25    )
26    =>
27    {
28      $Name!();
29      $crate::index!( $( $( $Rest )* )? );
30    };
31
32  }
33
34  /// Define implementation putting each function under a macro.
35  #[ macro_export ]
36  macro_rules! impls1
37  {
38
39    () => {};
40    (
41      $( #[ $Meta : meta ] )*
42      $Vis : vis
43      fn $Name : ident
44      $( $Rest : tt )*
45    )
46    =>
47    {
48      $crate::impls1!
49      {
50        @DefineFn
51        @Meta{ $( #[ $Meta ] )* }
52        @Vis{ $Vis }
53        @Name{ $Name }
54        @Rest
55          $( #[ $Meta ] )*
56          $Vis fn $Name
57          $( $Rest )*
58      }
59    };
60
61    (
62      @DefineFn
63      @Meta{ $( #[ $Meta : meta ] )* }
64      @Vis{ $Vis : vis }
65      @Name{ $Name : ident }
66      @Rest
67        $Item : item
68        $( $Rest : tt )*
69    )
70    =>
71    {
72      #[ deny( unused_macros ) ]
73      macro_rules! $Name
74      {
75        () =>
76        {
77          $Item
78        };
79      }
80
81      $crate::impls1!
82      {
83        $( $Rest )*
84      }
85    };
86
87  }
88
89  // qqq : cover by tests
90  // qqq : document the idea and module
91  // qqq : add section idea to each module
92
93  /// Define implementation putting each function under a macro.
94  /// Use [index!] to generate code for each element.
95  /// Unlike elements of [`impls_optional`!], elements of [`impls`] are mandatory to be used in [`index`!].
96  #[ macro_export ]
97  macro_rules! impls_optional
98  {
99
100    () => {};
101    (
102      $( #[ $Meta : meta ] )*
103      $Vis : vis
104      fn $Name : ident
105      $( $Rest : tt )*
106    )
107    =>
108    {
109      $crate::impls_optional!
110      {
111        @DefineFn
112        @Meta{ $( #[ $Meta ] )* }
113        @Vis{ $Vis }
114        @Name{ $Name }
115        @Rest
116          $( #[ $Meta ] )*
117          $Vis fn $Name
118          $( $Rest )*
119      }
120    };
121
122    (
123      @DefineFn
124      @Meta{ $( #[ $Meta : meta ] )* }
125      @Vis{ $Vis : vis }
126      @Name{ $Name : ident }
127      @Rest
128        $Item : item
129        $( $Rest : tt )*
130    )
131    =>
132    {
133      #[ allow( unused_macros ) ]
134      macro_rules! $Name
135      {
136        () =>
137        {
138          $Item
139        };
140      }
141
142      $crate::impls_optional!
143      {
144        $( $Rest )*
145      }
146    };
147
148  }
149  /// Define implementation putting each function under a macro and adding attribute `#[ test ]`.
150  /// Use [index!] to generate code for each element.
151  /// Unlike elements of [`test_impls_optional`!], elements of [`test_impls`] are mandatory to be used in [`index`!].
152  #[ macro_export ]
153  macro_rules! tests_impls
154  {
155
156    // empty
157
158    // () => { type X = i32; };
159
160    // empty
161
162    () => {};
163
164    // entry
165
166    (
167      $( #[ $Meta : meta ] )*
168      $Vis : vis
169      fn $Name : ident
170      $( $Rest : tt )*
171    )
172    =>
173    {
174      $crate::tests_impls!
175      {
176        @DefineFn
177        @Meta{ $( #[ $Meta ] )* }
178        @Vis{ $Vis }
179        @Name{ $Name }
180        @Rest
181          $( #[ $Meta ] )*
182          $Vis fn $Name
183          $( $Rest )*
184      }
185    };
186
187    // parsed
188
189    (
190      @DefineFn
191      @Meta{ $( #[ $Meta : meta ] )* }
192      @Vis{ $Vis : vis }
193      @Name{ $Name : ident }
194      @Rest
195        $Item : item
196        $( $Rest : tt )*
197    )
198    =>
199    {
200      #[ deny( unused_macros ) ]
201      macro_rules! $Name
202      {
203        () =>
204        {
205          #[ test ]
206          $Item
207        };
208      }
209
210      $crate::tests_impls!
211      {
212        $( $Rest )*
213      }
214    };
215
216  }
217
218  /// Define implementation putting each function under a macro and adding attribute `#[ test ]`.
219  /// Use [index!] to generate code for each element.
220  /// Unlike elements of [`test_impls`!], elements of [`test_impls_optional`] are optional to be used in [`index`!].
221  #[ macro_export ]
222  macro_rules! tests_impls_optional
223  {
224
225    // empty
226
227    // () => { type X = i32; };
228
229    // empty
230
231    () => {};
232
233    // entry
234
235    (
236      $( #[ $Meta : meta ] )*
237      $Vis : vis
238      fn $Name : ident
239      $( $Rest : tt )*
240    )
241    =>
242    {
243      $crate::tests_impls_optional!
244      {
245        @DefineFn
246        @Meta{ $( #[ $Meta ] )* }
247        @Vis{ $Vis }
248        @Name{ $Name }
249        @Rest
250          $( #[ $Meta ] )*
251          $Vis fn $Name
252          $( $Rest )*
253      }
254    };
255
256    // parsed
257
258    (
259      @DefineFn
260      @Meta{ $( #[ $Meta : meta ] )* }
261      @Vis{ $Vis : vis }
262      @Name{ $Name : ident }
263      @Rest
264        $Item : item
265        $( $Rest : tt )*
266    )
267    =>
268    {
269      #[ allow( unused_macros ) ]
270      macro_rules! $Name
271      {
272        () =>
273        {
274          #[ test ]
275          $Item
276        };
277      }
278
279      $crate::tests_impls_optional!
280      {
281        $( $Rest )*
282      }
283    };
284
285  }
286
287  /// Define implementation putting each function under a macro.
288  #[ macro_export ]
289  macro_rules! impls2
290  {
291
292    (
293      $( $Rest : tt )*
294    )
295    =>
296    {
297      $crate::fns!
298      {
299        @Callback { $crate::_impls_callback }
300        @Fns { $( $Rest )* }
301      }
302    };
303
304  }
305
306  /// Internal impls1 macro. Don't use.
307  #[ macro_export ]
308  macro_rules! _impls_callback
309  {
310
311    (
312      $( #[ $Meta : meta ] )*
313      $Vis : vis
314      fn $Name : ident
315      $( $Rest : tt )*
316    ) =>
317    {
318      #[ deny( unused_macros ) ]
319      macro_rules! $Name
320      {
321        ( as $Name2 : ident ) =>
322        {
323          $crate::fn_rename!{ @Name { $Name2 } @Fn
324          {
325            $( #[ $Meta ] )*
326            $Vis
327            fn $Name
328            $( $Rest )*
329          }}
330        };
331        () =>
332        {
333          $( #[ $Meta ] )*
334          $Vis
335          fn $Name
336          $( $Rest )*
337        };
338      }
339    };
340
341  }
342
343  pub use index;
344  pub use index as tests_index;
345  pub use impls1;
346  pub use impls_optional; /* qqq : write negative test. discuss please */
347  pub use tests_impls;
348  pub use tests_impls_optional; /* qqq : write negative test. discuss please */
349  pub use impls2;
350  pub use _impls_callback;
351
352}
353
354/// Exposed namespace of the module.
355#[ allow( unused_imports ) ]
356pub mod exposed
357{
358  use super::*;
359  #[ doc( inline ) ]
360  pub use prelude::*;
361
362  #[ doc( inline ) ]
363  pub use private::
364  {
365    index,
366    tests_index,
367    impls1,
368    impls_optional,
369    tests_impls,
370    tests_impls_optional,
371    impls2,
372    _impls_callback,
373  };
374  #[ doc( inline ) ]
375  pub use ::impls_index_meta::impls3;
376  #[ doc( inline ) ]
377  pub use impls3 as impls;
378
379}
380
381/// Prelude to use essentials: `use my_module::prelude::*`.
382#[ allow( unused_imports ) ]
383pub mod prelude
384{
385  use super::*;
386}