1#[proc_macro_derive(Effect, attributes(input))]
7pub fn derive_effect(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
8 let syn::DeriveInput { attrs, ident, .. } = syn::parse_macro_input!(input);
9
10 let input_ty = match attrs.iter().find(|a| a.path.is_ident("input")) {
11 Some(limit) => limit.parse_args::<syn::Type>().unwrap(),
12 None => panic!(),
13 };
14
15 let t = quote::quote! {
16 impl Effect for #ident {
17 type Input = #input_ty;
18 }
19 };
20 t.into()
21}
22
23#[proc_macro_derive(Composable, attributes(part))]
24pub fn derive_composable(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
25 let syn::DeriveInput { ident, data, .. } = syn::parse_macro_input!(input);
26
27 let it = match data {
28 syn::Data::Enum(e) => e.variants.into_iter().filter_map(|v| {
29 let ident = v.ident;
30 v.attrs
31 .into_iter()
32 .find(|a| a.path.is_ident("part"))
33 .map(|part| (part.parse_args::<syn::Type>().unwrap(), ident))
34 }),
35 _ => panic!(),
36 };
37 let (ty, id): (Vec<syn::Type>, Vec<syn::Ident>) = it.unzip();
38
39 let t = quote::quote! {
40 #(
41 impl Composable<#ty> for #ident {
42 fn take(output: &aeiou::Context<Self>) -> Option<#ty> {
43 match output.0.borrow_mut().take()? {
44 #ident::#id(v) => Some(#ty(v)),
45 _ => None,
46 }
47 }
48 }
49 )*
50 };
51 t.into()
52}