spectacle_impl_tuples/
lib.rs1use proc_macro::TokenStream;
5use quote::{format_ident, quote};
6use syn::{
7 parse::{Parse, ParseStream, Result},
8 parse_macro_input,
9};
10
11struct UpTo {
12 value: usize,
13}
14
15impl Parse for UpTo {
16 fn parse(input: ParseStream) -> Result<Self> {
17 let lit: syn::LitInt = input.parse()?;
18 let value = lit.base10_parse::<usize>()?;
19 Ok(UpTo { value })
20 }
21}
22
23#[proc_macro]
24pub fn impl_tuples(tokens: TokenStream) -> TokenStream {
25 let up_to = parse_macro_input!(tokens as UpTo);
26
27 let mut out = quote! {};
28
29 for arity in 0..=up_to.value {
30 let t_n = (0..arity)
31 .map(|n| format_ident!("T{}", n))
32 .collect::<Vec<_>>();
33 let idx = (0..arity).map(syn::Index::from).collect::<Vec<_>>();
34
35 out = quote! {
36 #out
37
38 impl<#(#t_n),*> Introspect for (#(#t_n,)*)
39 where
40 #(
41 #t_n: 'static + Introspect,
42 )*
43 {
44 fn introspect_from<F>(&self, breadcrumbs: Breadcrumbs, mut visit: F)
45 where
46 F: FnMut(&Breadcrumbs, &dyn Any),
47 {
48 visit(&breadcrumbs, self);
49
50 #({
51 let mut breadcrumbs = breadcrumbs.clone();
52 breadcrumbs.push_back(Breadcrumb::TupleIndex(#idx));
53 self.#idx.introspect_from(breadcrumbs, &mut visit);
54 })*
55 }
56 }
57 }
58 }
59
60 out.into()
63}