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 38 39 40 41
extern crate proc_macro; use proc_macro::TokenStream; use syn::{parse_macro_input, Data, DeriveInput, Fields}; use quote::quote; #[proc_macro_derive(TurtleContainer, attributes(turtle))] pub fn derive_turtle_container(input: TokenStream) -> TokenStream { let input: DeriveInput = parse_macro_input!(input as DeriveInput); let mut gen = None; if let Data::Struct(ref data) = input.data { if let Fields::Named(ref fields) = data.fields { for field in fields.named.iter() { for attr in field.attrs.iter() { if attr.path.is_ident("turtle") { let field_type = &field.ty; let field_ident = &field.ident; let struct_ident = &input.ident; gen = Some(quote! { impl dcc_lsystem::turtle::TurtleContainer for #struct_ident { type Item = <#field_type as dcc_lsystem::turtle::MovingTurtle>::Item; fn inner(&self) -> &dyn dcc_lsystem::turtle::MovingTurtle<Item = Self::Item> { &self.#field_ident } } }); } } } } } if let Some(gen) = gen { gen.into() } else { TokenStream::new() } }