use crate::add_like; use crate::mul_helpers::generics_and_exprs; use crate::utils::{AttrParams, MultiFieldData, RefType, State}; use proc_macro2::{Span, TokenStream}; use quote::quote; use std::collections::HashSet; use std::iter; use syn::{DeriveInput, Ident, Result}; pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result { let mut state = State::with_attr_params( input, trait_name, quote!(::core::ops), trait_name.to_lowercase(), AttrParams::struct_(vec!["forward"]), )?; if state.default_info.forward { return Ok(add_like::expand(input, trait_name)); } let scalar_ident = &Ident::new("__RhsT", Span::call_site()); state.add_trait_path_type_param(quote!(#scalar_ident)); let multi_field_data = state.enabled_fields_data(); let MultiFieldData { input_type, field_types, ty_generics, trait_path, trait_path_with_params, method_ident, .. } = multi_field_data.clone(); let tys = field_types.iter().collect::>(); let tys = tys.iter(); let scalar_iter = iter::repeat(scalar_ident); let trait_path_iter = iter::repeat(trait_path); let type_where_clauses = quote! { where #(#tys: #trait_path_iter<#scalar_iter, Output=#tys>),* }; let (generics, initializers) = generics_and_exprs( multi_field_data.clone(), scalar_ident, type_where_clauses, RefType::No, ); let body = multi_field_data.initializer(&initializers); let (impl_generics, _, where_clause) = generics.split_for_impl(); Ok(quote!( impl#impl_generics #trait_path_with_params for #input_type#ty_generics #where_clause { type Output = #input_type#ty_generics; #[inline] fn #method_ident(self, rhs: #scalar_ident) -> #input_type#ty_generics { #body } } )) }