1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
use proc_macro2::Span;
use proc_macro::TokenStream;
use syn::{parse_macro_input, DeriveInput};
use quote::quote;

#[proc_macro_attribute]
pub fn extendable_enum(args: TokenStream, source: TokenStream) -> TokenStream {
    let mut name_string = args.to_string();
    let source_ast = parse_macro_input!(source as DeriveInput);
    if args.is_empty() {
        name_string = format!("extend_from_{}", source_ast.ident);
    }
    let name = syn::Ident::new(&name_string, Span::call_site());
    TokenStream::from(quote! {
        use quote::quote;
        use proc_macro2::TokenStream as TokenStream2;
        use proc_macro::TokenStream;

        #[proc_macro_attribute]
        pub fn #name(_attr: TokenStream, dst: TokenStream) -> TokenStream {
            let base = TokenStream2::from(quote! {
                #source_ast
            });
            let dst_convert: TokenStream2 = dst.into();
            let resp: TokenStream = extendable_enums_helpers::combine_enums(base, dst_convert).into();
            resp
        }
    })
}