formatted_index_macro/
lib.rs1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, Data, DeriveInput};
4
5#[proc_macro_derive(FormattedIndex)]
6pub fn formatted_index_derive(input: TokenStream) -> TokenStream {
7 let input = parse_macro_input!(input as DeriveInput);
9
10 let name = &input.ident;
12
13 let data_enum = match input.data {
15 Data::Enum(data_enum) => data_enum,
16 _ => {
17 return quote! {
18 compile_error!("FormattedIndex can only be derived for enums");
19 }
20 .into()
21 }
22 };
23
24 let variants = data_enum.variants.iter().enumerate().map(|(i, variant)| {
26 let variant_name = &variant.ident;
27 let one_based_index = i + 1;
29 let formatted_index = format!("[{one_based_index}]");
30
31 quote! {
32 #name::#variant_name { .. } => #formatted_index,
33 }
34 });
35
36 let expanded = quote! {
38 impl #name {
39 pub const fn to_formatted_index(&self) -> &'static str {
41 match self {
42 #(#variants)*
43 }
44 }
45 }
46 };
47
48 TokenStream::from(expanded)
49}