1 | use crate::add_like; |
2 | use crate::mul_helpers::generics_and_exprs; |
3 | use crate::utils::{AttrParams, MultiFieldData, RefType, State}; |
4 | use proc_macro2::{Span, TokenStream}; |
5 | use quote::quote; |
6 | use std::collections::HashSet; |
7 | use std::iter; |
8 | use syn::{DeriveInput, Ident, Result}; |
9 | |
10 | pub fn expand(input: &DeriveInput, trait_name: &'static str) -> Result<TokenStream> { |
11 | let mut state = State::with_attr_params( |
12 | input, |
13 | trait_name, |
14 | quote!(::core::ops), |
15 | trait_name.to_lowercase(), |
16 | AttrParams::struct_(vec!["forward" ]), |
17 | )?; |
18 | if state.default_info.forward { |
19 | return Ok(add_like::expand(input, trait_name)); |
20 | } |
21 | |
22 | let scalar_ident = &Ident::new("__RhsT" , Span::call_site()); |
23 | state.add_trait_path_type_param(quote!(#scalar_ident)); |
24 | let multi_field_data = state.enabled_fields_data(); |
25 | let MultiFieldData { |
26 | input_type, |
27 | field_types, |
28 | ty_generics, |
29 | trait_path, |
30 | trait_path_with_params, |
31 | method_ident, |
32 | .. |
33 | } = multi_field_data.clone(); |
34 | |
35 | let tys = field_types.iter().collect::<HashSet<_>>(); |
36 | let tys = tys.iter(); |
37 | let scalar_iter = iter::repeat(scalar_ident); |
38 | let trait_path_iter = iter::repeat(trait_path); |
39 | |
40 | let type_where_clauses = quote! { |
41 | where #(#tys: #trait_path_iter<#scalar_iter, Output=#tys>),* |
42 | }; |
43 | |
44 | let (generics, initializers) = generics_and_exprs( |
45 | multi_field_data.clone(), |
46 | scalar_ident, |
47 | type_where_clauses, |
48 | RefType::No, |
49 | ); |
50 | let body = multi_field_data.initializer(&initializers); |
51 | let (impl_generics, _, where_clause) = generics.split_for_impl(); |
52 | Ok(quote!( |
53 | impl#impl_generics #trait_path_with_params for #input_type#ty_generics #where_clause { |
54 | type Output = #input_type#ty_generics; |
55 | #[inline] |
56 | fn #method_ident(self, rhs: #scalar_ident) -> #input_type#ty_generics { |
57 | #body |
58 | } |
59 | } |
60 | |
61 | )) |
62 | } |
63 | |