1extern crate proc_macro;
2extern crate quote;
3extern crate syn;
4
5use proc_macro::TokenStream;
6use quote::quote;
7
8#[proc_macro_derive(Lerp)]
14pub fn lerp_macro_derive(input: TokenStream) -> TokenStream {
15 let ast = syn::parse(input).unwrap();
16 impl_lerp_macro(&ast)
17}
18
19fn impl_lerp_macro(ast: &syn::DeriveInput) -> TokenStream {
20 use syn::Fields;
21
22 let name = &ast.ident;
23 let data: &syn::Data = &ast.data;
24 match data {
25 syn::Data::Struct(struct_data) => {
26 let mut field_assignment_tokens = quote!();
27 match &struct_data.fields {
28 Fields::Named(named) => {
29 for field in named.named.iter() {
30 let field_name = field.ident.as_ref();
31 field_assignment_tokens.extend(
32 quote!(output.#field_name = self.#field_name * (1.0 - amount) + amount * other.#field_name;)
33 );
34 }
35 }
36 _ => unimplemented!(),
37 }
38
39 let tokens = quote! {
40 impl Lerp<#name> for #name {
41 fn lerp(&self, other: &Self, amount: f64) -> Self {
42 let mut output = self.clone();
43 #field_assignment_tokens
45 return output;
46 }
47 }
48 };
49 tokens.into()
50 }
51
52 _ => unimplemented!(),
53 }
54}