cranenum/
lib.rs

1extern crate proc_macro;
2use proc_macro::TokenStream;
3use quote::{quote};
4use syn::{parse_macro_input, DeriveInput, Data};
5
6#[proc_macro_derive(Cranenum)]
7pub fn cranenum(input: TokenStream) -> TokenStream {
8    let input = parse_macro_input!(input as DeriveInput);
9    let ident = input.ident;
10
11    let variants = match &input.data {
12        Data::Enum(data) => &data.variants,
13        _ => {
14            panic!("#[derive(Cranenum)] can only be applied to enums");
15        }
16    };
17
18    let outputs = variants.iter().map(|variant| {
19        let field = variant.fields.iter().nth(0).unwrap();
20        let from = &field.ty;
21        let variant_ident = &variant.ident;
22
23        let output = quote! {
24            impl std::convert::From<#from> for #ident {
25                fn from(item: #from) -> Self {
26                    #ident::#variant_ident(item)
27                }
28            }
29        };
30        TokenStream::from(output)
31    }).collect::<TokenStream>();
32
33    outputs.into()
34}