derive_more_impl/
mul_like.rs

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