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
36
37
use proc_macro::TokenStream;
use quote::*;
use syn::*;
#[proc_macro_derive(Mergeable)]
pub fn mergeable(input: TokenStream) -> TokenStream {
let strukt: ItemStruct = parse_macro_input! { input };
let mut methods = vec![];
for field in strukt.fields.clone() {
let name = field.ident.unwrap();
let tokens = quote! {
let #name = most_frequent(items.iter().map(|x| x.#name.to_owned()).collect::<Vec<_>>()).to_owned();
};
methods.push(tokens);
}
let field = strukt.fields.iter().map(|x| x.ident.as_ref().unwrap());
let name = strukt.ident;
let tokens = quote! {
impl #name {
pub fn merge(items: Vec<Self>) -> Option<Self> {
use crate::util::most_frequent;
if items.is_empty() {
return None;
}
#(#methods)*
Some(Self {
#(#field),*
})
}
}
};
tokens.into()
}