trident_derive_displayix/
lib.rs1use proc_macro::TokenStream;
2use quote::quote;
3use syn::{parse_macro_input, Data, DeriveInput};
4
5#[proc_macro_derive(DisplayIx)]
6pub fn display_ix(input: TokenStream) -> TokenStream {
7 let input = parse_macro_input!(input as DeriveInput);
8 let enum_name = &input.ident;
9
10 let display_impl = match &input.data {
11 Data::Enum(enum_data) => {
12 let to_context_string_match_arms = enum_data.variants.iter().map(|variant| {
13 let variant_name = &variant.ident;
14 quote! {
15 #enum_name::#variant_name (_) => String::from(stringify!(#variant_name)),
16 }
17 });
18 let display_match_arms = enum_data.variants.iter().map(|variant| {
19 let variant_name = &variant.ident;
20
21 match &variant.fields {
22 syn::Fields::Unnamed(fields) => {
23 if fields.unnamed.len() == 1 {
24 quote! {
25 #enum_name::#variant_name(ref content) => {
26 write!(f, stringify!(#variant_name))?;
27 write!(f, "({:#?})", content)
28 },
29 }
30 } else {
31 quote! {
32 #enum_name::#variant_name (_) => write!(f, stringify!(#variant_name)),
33 }
34 }
35 },
36 _ => quote! {
37 #enum_name::#variant_name => write!(f, stringify!(#variant_name)),
38 },
39 }
40 });
41
42 quote! {
43 impl std::fmt::Display for #enum_name {
44 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45 match self {
46 #(#display_match_arms)*
47 }
48 }
49 }
50 impl #enum_name {
51 fn to_context_string(&self)->String{
52 match self {
53 #(#to_context_string_match_arms)*
54 }
55 }
56 }
57 }
58 }
59 _ => panic!("DisplayIx can only be derived for enums"),
60 };
61
62 TokenStream::from(display_impl)
63}