ribir_macros 0.2.0-alpha.4

Ribir is a framework for building modern native/wasm cross-platform user interface applications.
Documentation
use crate::util::data_struct_unwrap;
use proc_macro2::TokenStream;
use quote::quote;
use syn::spanned::Spanned;

pub(crate) fn lerp_derive(input: &mut syn::DeriveInput) -> syn::Result<TokenStream> {
  let syn::DeriveInput { ident: name, generics, data, .. } = input;
  let (g_impl, g_ty, g_where) = generics.split_for_impl();
  let stt = data_struct_unwrap(data, "Lerp")?;

  let tokens = match &stt.fields {
    syn::Fields::Named(n) => {
      let fields = n.named.iter().map(|f| &f.ident);
      quote! {
        impl #g_impl Lerp for #name #g_ty #g_impl #g_where {
          fn lerp(&self, to: &Self, factor: f32) -> Self {
            #name {
              #(#fields: self.#fields.lerp(&to.#fields, factor)),*
            }
          }
        }
      }
    }
    syn::Fields::Unnamed(u) => {
      let indexes = u
        .unnamed
        .iter()
        .enumerate()
        .map(|(i, f)| syn::Index { index: i as u32, span: f.span() });
      quote! {
        impl #g_impl Lerp for #name #g_ty #g_impl #g_where {
          fn lerp(&self, to: &Self, factor: f32) -> Self {
            #name( #(self.#indexes.lerp(&to.#indexes, factor)) ,*)
          }
        }
      }
    }
    syn::Fields::Unit => quote! {
      impl #g_impl Lerp for #name #g_ty #g_impl #g_where {
        fn lerp(&self, to: &Self, factor: f32) -> Self {
           #name
        }
      }
    },
  };

  Ok(tokens)
}