tstr_proc_macros/
nested_tuple_compute.rs
1use crate::{
4 used_proc_macro::{Span, TokenStream},
5 utils::{paren, punct_token},
6};
7
8use std::iter;
9
10#[cfg(test)]
11mod tests;
12
13#[must_use]
14pub(crate) fn compute<T, F>(input: &[T], span: Span, func: &mut F) -> TokenStream
15where
16 F: FnMut(&[T], &mut TokenStream),
17{
18 let mut out = TokenStream::new();
19
20 if input.is_empty() {
21 out.extend(std::iter::once(paren(span, |_| ())));
22 } else if input.len() <= CHUNK_SIZE {
23 func(input, &mut out);
24 } else {
25 let tt = paren(span, |out| {
26 let lower_power = find_smaller_power(input.len());
27
28 for chunk in input.chunks(lower_power) {
29 out.extend(compute(chunk, span, func));
30 out.extend(punct_token(',', span));
31 }
32 });
33 out.extend(iter::once(tt));
34 }
35
36 out
37}
38
39const CHUNK_SIZE: usize = 8;
40
41fn find_smaller_power(than: usize) -> usize {
42 let mut curr = 1;
43 loop {
44 let next = curr * 8;
45 if next >= than {
46 break curr;
47 } else {
48 curr = next;
49 }
50 }
51}