extendable_data_helpers/
lib.rs1use proc_macro2::{Ident, Span};
2use proc_macro::TokenStream;
3use syn::{parse_macro_input, DeriveInput};
4use quote::quote;
5
6#[proc_macro_attribute]
12pub fn extendable_data(args: TokenStream, source: TokenStream) -> TokenStream {
13 let mut name_string = args.to_string();
14 let mut source_ast = parse_macro_input!(source as DeriveInput);
15 if args.is_empty() {
16 name_string = format!("extend_from_{}", source_ast.ident);
17 }
18 let name = Ident::new(&name_string, Span::call_site());
19 let mut docs = Vec::new();
20 let mut attrs = Vec::new();
21 for attr in std::mem::take(&mut source_ast.attrs) {
22 let doc: bool = if let syn::Meta::NameValue(ref meta) = attr.meta {
23 if let Some(ident) = meta.path.get_ident() {
24 ident == "doc"
25 } else {
26 false
27 }
28 } else {
29 false
30 };
31 if doc {
32 docs.push(attr);
33 } else {
34 attrs.push(attr);
35 }
36 }
37 TokenStream::from(quote! {
38 #(#docs)*
39 #[proc_macro_attribute]
40 pub fn #name(args: proc_macro::TokenStream, dst: proc_macro::TokenStream) -> proc_macro::TokenStream {
41 let base = proc_macro2::TokenStream::from(quote::quote! {
42 #(#attrs)*
43 #source_ast
44 });
45 let dst_convert: proc_macro2::TokenStream = dst.into();
46 let args_convert: proc_macro2::TokenStream = args.into();
47 extendable_data::combine_data(base, dst_convert, Some(args_convert)).into()
48 }
49 })
50}