use proc_macro2::TokenStream as TokenStream2;
use quote::quote;
use crate::parser::*;
pub(crate) struct FieldTokensLerpable {
pub(crate) for_lerpable: TokenStream2,
}
impl GenFinal for FieldTokensLerpable {
fn make_newtype_struct_final(
idents: ParsedFieldIdent,
variants: Vec<FieldTokensLerpable>,
) -> TokenStream2 {
let name = idents.name;
let for_lerpable = variants.iter().map(|x| x.for_lerpable.clone());
quote! {
impl lerpable::Lerpable for #name {
fn lerpify<T: lerpable::IsLerpingMethod>(&self, other: &Self, pct: &T) -> Self {
#name(#(#for_lerpable,)*)
}
}
}
}
fn make_struct_final(
idents: ParsedFieldIdent,
variants: Vec<FieldTokensLerpable>,
) -> TokenStream2 {
let name = idents.name;
let for_lerpable = variants.iter().map(|a| a.for_lerpable.clone());
quote! {
impl lerpable::Lerpable for #name {
fn lerpify<T: lerpable::IsLerpingMethod>(&self, other: &Self, pct: &T) -> Self {
#name {
#(#for_lerpable,)*
}
}
}
}
}
fn make_enum_final(
idents: ParsedFieldIdent,
variants: Vec<FieldTokensLerpable>,
) -> TokenStream2 {
let name = idents.name;
let for_lerpable = variants.iter().map(|a| a.for_lerpable.clone());
quote! {
impl lerpable::Lerpable for #name {
fn lerpify<T: lerpable::IsLerpingMethod>(&self, other: &Self, pct: &T) -> Self {
match (self, other) {
#(#for_lerpable,)*
_ => lerpable::step(self, other, pct)
}
}
}
}
}
fn from_newtype_struct(idents: StructIdents, _parent_ident: syn::Ident) -> FieldTokensLerpable {
let method_def = idents.to_method_override();
let lerpify = if let Some(func) = idents.func() {
quote! { #func(&self.0, &other.0, method) }
} else {
quote! { self.0.lerpify(&other.0, method) }
};
let for_lerpable = quote! {
{
#method_def
#lerpify
}
};
FieldTokensLerpable { for_lerpable }
}
fn from_unnamed_enum(idents: EnumIdents) -> FieldTokensLerpable {
let variant_ident = idents.variant_ident();
let name = idents.enum_ident();
let for_lerpable = match idents.how_to_control_internal() {
HowToControlThis::Skip => quote! {
(#name::#variant_ident(self_s), #name::#variant_ident(other_s)) => #name::#variant_ident(lerpable::step(&self_s, &other_s, pct))
},
HowToControlThis::LerpifyType => quote! {
(#name::#variant_ident(self_s), #name::#variant_ident(other_s)) => #name::#variant_ident(self_s.lerpify(&other_s, pct))
},
};
FieldTokensLerpable { for_lerpable }
}
fn from_unit_enum(idents: EnumIdents) -> FieldTokensLerpable {
let variant_ident = idents.variant_ident();
let name = idents.enum_ident();
let for_lerpable: TokenStream2 = {
quote! { (#name::#variant_ident, #name::#variant_ident) => lerpable::step(self, other, pct) }
};
FieldTokensLerpable { for_lerpable }
}
fn from_noop_struct(idents: StructIdents) -> FieldTokensLerpable {
let name = idents.name();
let method_def = idents.to_method_override();
let for_lerpable: TokenStream2 = quote! {
#name: {
#method_def;
lerpable::step(&self.#name, &other.#name, method)
}
};
FieldTokensLerpable { for_lerpable }
}
fn from_type_struct(idents: StructIdents) -> FieldTokensLerpable {
let name = idents.name();
let method_def = idents.to_method_override();
let lerpify = if let Some(func) = idents.func() {
quote! { #func(&self.#name, &other.#name, method) }
} else {
quote! { self.#name.lerpify(&other.#name, method) }
};
let for_lerpable = {
quote! { #name: {
#method_def
#lerpify
}}
};
FieldTokensLerpable { for_lerpable }
}
}