ribir_macros 0.4.0-alpha.41

A non-intrusive declarative GUI framework, to build modern native/wasm cross-platform applications.
Documentation
use proc_macro2::TokenStream;
use quote::quote;
use syn::spanned::Spanned;

use crate::util::data_struct_unwrap;

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_where {
          fn lerp(&self, to: &Self, factor: f32) -> Self {
            #name {
              #(#fields: Lerp::lerp(&self.#fields, &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_where {
          fn lerp(&self, to: &Self, factor: f32) -> Self {
            #name(#(Lerp::lerp(&self.#indexes, &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)
}