konst_macro_rules/
iter.rs

1mod combinator_methods;
2mod iter_eval_macro;
3
4#[macro_export]
5macro_rules! for_each {
6    ($pattern:pat in $($rem:tt)*) => ({
7        $crate::__process_iter_args!{
8            ($crate::__for_each)
9            (($pattern),)
10            (
11                item,
12                'zxe7hgbnjs,
13                adapter,
14            )
15            $($rem)*
16        }
17    });
18}
19
20#[doc(hidden)]
21#[macro_export]
22macro_rules! __for_each {
23    (
24        @each
25        ($pattern:pat),
26        ($item:ident adapter),
27        $(,)? => $($code:tt)*
28    ) => ({
29        let $pattern = $item;
30        $($code)*
31    });
32    (@$other:ident $($tt:tt)*) =>{};
33}
34
35#[macro_export]
36macro_rules! iter_count {
37    ($iter:expr $(,)*) => {{
38        let mut count = 0;
39        $crate::for_each! {_ in $iter => {count+=1;}}
40        count
41    }};
42}
43
44macro_rules! make__cim_preprocess_methods__macro {
45    (
46        $_:tt
47        [$(
48            $fn:ident [$($next_fn:ident)?] $args:tt
49            $(return $ret_var:tt)?
50            $(var $new_var:tt)?,
51        )*]
52        [$(
53            ($($st_func:ident)* ($($func_args:tt)*)) => { $var:ident = $var_expr:tt }
54        )*]
55        $($finished_arm:tt)*
56    ) => {
57        #[doc(hidden)]
58        #[macro_export]
59        macro_rules! __cim_method_not_found_err {
60            ($func:ident $($_($fn)?)* $($($_($st_func)?)*)*) => {
61                $crate::__::compile_error! {$crate::__::concat!{
62                    "the `",
63                    $crate::__::stringify!($func),
64                    "` method cannot be called in this macro",
65                }}
66            };
67            ($func:ident $func2:ident) => {
68                $crate::__::compile_error!{$crate::__::concat!(
69                    "Unsupported iterator method: `",
70                    $crate::__::stringify!($func),
71                    "`",
72                )}
73            };
74        }
75
76        #[doc(hidden)]
77        #[macro_export]
78        macro_rules! __cim_preprocess_methods {
79            $($finished_arm)*
80
81            $(
82                (
83                    (($_($vars_after:tt)*) $_($fixed:tt)*)
84                    [$prev_next_fn:ident $_($ignored:tt)*]
85
86                    $func_:ident $_($fn)? $args,
87                    $_($rest:tt)*
88                ) => ({
89                    $( $crate::__assert_first_rev!{$func_ $prev_next_fn $next_fn} )?
90
91                    $crate::iter::__cim_preprocess_methods!{
92                        (
93                            (
94                                $(return(rets = $ret_var))?
95                                $_($vars_after)*
96                                $((var = $new_var))?
97                            )
98                            $_($fixed)*
99                        )
100                        [$($next_fn)? $prev_next_fn]
101                        $_($rest)*
102                    }
103                });
104            )*
105
106            $(
107                (
108                    (($_($vars_before:tt)*) $_($fixed:tt)*)
109                    [$prev_next_fn:ident $_($ignored:tt)*]
110
111                    $func_:ident $($_($st_func)?)* ($($func_args)*),
112                    $_($rest:tt)*
113                ) => ({
114                    $crate::iter::__cim_preprocess_methods!{
115                        (($_($vars_before)* ($var = $var_expr)) $_($fixed)*)
116                        [$prev_next_fn]
117                        $_($rest)*
118                    }
119                });
120            )*
121
122
123            (
124                $fixed:tt
125                $prev_next_fn:tt
126
127                $func:ident $func2:ident ($_($args_:tt)*),
128                $_($rest:tt)*
129            ) => {
130                $crate::__::compile_error!{$crate::__::concat!(
131                    "unsupported iterator method: ",
132                    $crate::__::stringify!($func),
133                )}
134            }
135        }
136
137        #[doc(hidden)]
138        pub use __cim_preprocess_methods;
139
140        #[doc(hidden)]
141        pub use __cim_method_not_found_err;
142    };
143}
144
145make__cim_preprocess_methods__macro! {
146    $
147    [
148        copied[] ($($args:tt)*),
149        filter[] ($($args:tt)*),
150        filter_map[] ($($args:tt)*),
151        flat_map[] ($($args:tt)*),
152        flatten[] ($($args:tt)*),
153        map[] ($($args:tt)*),
154        take_while[] ($($args:tt)*),
155        rev[next_back] ($($args:tt)*),
156
157        rfind[next_back] ($($args:tt)*)
158            return($crate::__::None),
159
160        all[] ($($args:tt)*)
161            return(true),
162
163        any[] ($($args:tt)*)
164            return(false),
165
166        count[] ($($args:tt)*)
167            return(0usize),
168
169        find[] ($($args:tt)*)
170            return($crate::__::None),
171
172        find_map[] ($($args:tt)*)
173            return($crate::__::None),
174
175        rfold[next_back] ($($args:tt)*)
176            return($crate::__assert_fold_accum!(rfold, $($args)*)),
177
178        fold[] ($($args:tt)*)
179            return($crate::__assert_fold_accum!(fold, $($args)*)),
180
181        for_each[] ($($args:tt)*),
182
183        nth[] ($($args:tt)*)
184            return($crate::__::None)
185            var({
186                let x: $crate::__::usize = $crate::__cim_assert_expr!{nth($($args)*), 0usize};
187                x
188            }),
189
190        next[] ($($args:tt)*)
191            return($crate::__::None),
192
193        position[] ($($args:tt)*)
194            return($crate::__::None)
195            var(0usize),
196
197        rposition[next_back] ($($args:tt)*)
198            return($crate::__::None)
199            var(0usize),
200    ]
201
202    [
203        ( zip($($args:tt)*) ) => {
204            iter = (
205                $crate::into_iter_macro!(
206                    $crate::__cim_assert_expr!{zip($($args)*), 0usize..0}
207                )
208            )
209        }
210
211        ( enumerate($($args:tt)*) ) => {
212            i = { 0usize }
213        }
214
215        ( take skip ($($args:tt)*) ) => {
216            rem = {
217                let x: $crate::__::usize = $crate::__cim_assert_expr!{take($($args)*), 0};
218                x
219            }
220        }
221
222        ( skip_while ($($args:tt)*) ) => {
223            still_skipping = true
224        }
225    ]
226
227    (
228        (
229            (
230                $(return($ret_var:ident = $ret_val:tt))?
231                ($iter_var:ident = $iter_expr:expr);
232                $(($var:ident = $var_value:expr))*
233            )
234            ($($callback_macro:tt)*)
235            ($($fixed_arguments:tt)*)
236            (
237                $item:ident,
238                $label:lifetime,
239                // adapter: analogous to iterator adapter, which return iterators
240                // consumer: methods which consume the iterator without (necessarily)
241                //            returning an iterator.
242                $allowed_methods:ident,
243            )
244            ($($args:tt)*)
245        )
246        [$next_fn:ident $($ignored:tt)*]
247    ) => ({
248        $(let mut $ret_var = $ret_val;)?
249        $crate::__call_iter_methods!{
250            (
251                ($($var)* $($ret_var)?)
252                ($($callback_macro)*) ($($fixed_arguments)*)
253                ($label $label)
254                $next_fn
255                $allowed_methods
256            )
257            (
258                ($($var)* $($ret_var)?)
259                ($($callback_macro)*) ($($fixed_arguments)*)
260                ($label $label)
261                $next_fn
262                $allowed_methods
263            )
264            $item
265            (
266                (
267                    {
268                        $iter_var = $iter_expr,
269                        $($var = $var_value,)*
270                    }
271                    let $item = if let $crate::__::Some((elem_, next_)) = $iter_var.$next_fn() {
272                        $iter_var = next_;
273                        elem_
274                    } else {
275                        break $label;
276                    };
277                )
278            )
279            $($args)*
280        }
281        $($ret_var)?
282    });
283}
284
285#[doc(hidden)]
286#[macro_export]
287macro_rules! __assert_first_rev {
288    ($func:ident next_back next_back) => {
289        $crate::__::compile_error! {$crate::__::concat!(
290            "cannot call two iterator-reversing methods in `konst::iter` macros,",
291            " called: ",
292            $crate::__::stringify!($func),
293        )}
294    };
295    ($func:ident $prev_next_fn:ident $($next_fn:ident)?) => {};
296}
297
298#[doc(hidden)]
299#[macro_export]
300macro_rules! __cim_assert_expr {
301    ($func:ident (), $def:expr) => {{
302        $crate::__cim_no_expr_arg_error! {$func ()}
303        $def
304    }};
305    ($func:ident ( $expr:expr $(,)?), $def:expr) => {
306        $expr
307    };
308    ($func:ident ($expr:expr ,$($args:tt)+), $def:expr) => {{
309        $crate::__::compile_error! {$crate::__::concat!{
310            "`",
311            $crate::__::stringify!($func),
312            "` only takes one argument"
313        }}
314
315        $def
316    }};
317    ($func:ident $args:tt, $def:expr) => {{
318        $crate::__cim_no_expr_arg_error! {$func $args}
319        $def
320    }};
321}
322
323#[doc(hidden)]
324#[macro_export]
325macro_rules! __cim_no_expr_arg_error {
326    ($func:ident $args:tt) => {
327        $crate::__::compile_error! {$crate::__::concat!{
328            "`",
329            $crate::__::stringify!($func),
330            "` expected an expression to be passed, passed: ",
331            $crate::__cim_if_empty!{
332                $args {
333                    "``"
334                } else {
335                    $crate::__::stringify! $args
336                }
337            },
338        }}
339    };
340}
341
342#[doc(hidden)]
343#[macro_export]
344macro_rules! __cim_if_empty {
345    (() {$($then:tt)*} else $else:tt) => { $($then)* };
346    (() $then:tt else {$($else:tt)*}) => { $($else)* };
347}
348
349#[doc(hidden)]
350#[macro_export]
351macro_rules! __assert_fold_accum {
352    ($func:ident, $e:expr $(, $($__:tt)*)?) => {
353        $e
354    };
355    // dummy default value, this'll error in __iter_eval
356    ($func:ident, $($args:tt)*) => {
357        ()
358    };
359}