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 30 31 32 33 34 35
extern crate proc_macro; use proc_macro_hack::proc_macro_hack; #[proc_macro_hack] pub fn vecmerge(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let expr = syn::parse_macro_input!(input as syn::Expr); let mut elems = Vec::new(); extract(expr, &mut elems); let result = proc_quote::quote! {{ let mut v = Vec::new(); #(#elems)* v }}; result.into() } fn extract(expr: syn::Expr, elems: &mut Vec<proc_macro2::TokenStream>) { match expr { syn::Expr::Binary(expr) => { if let syn::BinOp::Add(..) = expr.op { extract(*expr.left, elems); extract(*expr.right, elems); } } syn::Expr::Array(array) => { for elem in array.elems.into_iter() { elems.push(proc_quote::quote!(v.push(#elem);)) } } vector => { elems.push(proc_quote::quote!(v.extend(#vector);)); } } }