array_const_fn_init/
lib.rs1extern crate proc_macro;
25
26use core::iter;
27use core::str::FromStr;
28use proc_macro::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
29
30#[proc_macro]
31pub fn array_const_fn_init(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
32 let mut iter = input.into_iter();
33
34 let func_name = match iter.next() {
35 Some(proc_macro::TokenTree::Ident(i)) => i.to_string(),
36 Some(other) => panic!("Expected function name, found {}", other),
37 None => panic!("Unexpected end of macro input"),
38 };
39
40 match iter.next() {
41 Some(proc_macro::TokenTree::Punct(ref p)) if p.as_char() == ';' => {}
42 Some(other) => panic!("Expected ';', found {}", other),
43 None => panic!("Unexpected end of macro input"),
44 };
45
46 let array_size: usize = match iter.next() {
47 Some(proc_macro::TokenTree::Literal(ref p)) => {
48 usize::from_str(&p.to_string()).expect("Expected <usize>")
49 }
50 Some(other) => panic!("Expected <usize>, found {}", other),
51 None => panic!("Unexpected end of macro input"),
52 };
53
54 match iter.next() {
55 None => {}
56 Some(_) => panic!("Unexpected trailing tokens in macro"),
57 }
58
59 let mut ts = TokenStream::new();
60 let span: Span = Span::call_site();
61 ts.extend({
62 let mut g = Group::new(Delimiter::Bracket, {
63 let mut ts = TokenStream::new();
64 (0..array_size).for_each(|i| {
65 ts.extend(iter::once(TokenTree::from(Ident::new(&func_name, span))));
66 ts.extend({
67 let mut g = Group::new(Delimiter::Parenthesis, {
68 let mut ts = TokenStream::new();
69 let _span: Span = span;
70 ts.extend(iter::once(TokenTree::from(Literal::usize_suffixed(i))));
71 ts
72 });
73 g.set_span(span);
74 Some(TokenTree::from(g))
75 });
76 ts.extend(iter::once(TokenTree::from(Punct::new(',', Spacing::Alone))));
77 });
78 ts
79 });
80 g.set_span(span);
81 Some(TokenTree::from(g))
82 });
83 ts
84}