type_census_derive/
lib.rs1use darling::FromDeriveInput;
2use proc_macro::{self, TokenStream};
3use quote::quote;
4use syn::{parse_macro_input, DeriveInput};
5
6#[derive(FromDeriveInput, Default)]
7#[darling(default, attributes(Tabulate), forward_attrs(allow, doc, cfg))]
8struct Opts {
9 #[darling(rename = "Counter")]
10 counter: Option<syn::TypePath>,
11}
12
13#[proc_macro_derive(Tabulate, attributes(Tabulate))]
14pub fn derive(input: TokenStream) -> TokenStream {
15 let input = parse_macro_input!(input);
16 let opts = Opts::from_derive_input(&input).expect("Wrong options");
17 let DeriveInput { ident, .. } = input;
18
19 let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
20
21 let counter_ty = match opts.counter {
22 Some(counter_ty) => quote! { #counter_ty },
23 None => quote! { type_census::counter::RelaxedCounter },
24 };
25
26 let output = quote! {
27 #[automatically_derived]
28 impl #impl_generics type_census::Tabulate for #ident #ty_generics #where_clause {
29 type Counter = #counter_ty;
30 fn counter() -> &'static #counter_ty {
31 static COUNTER: #counter_ty = <#counter_ty as type_census::counter::Counter>::ZERO;
32 &COUNTER
33 }
34 }
35 };
36 output.into()
37}