1use super::config::{BlanketParamName, EvalBlanketFlagParam};
2use super::{NamedMember, PosFnMember};
3use crate::builder::builder_gen::top_level_config::OnConfig;
4use crate::util::prelude::*;
56impl NamedMember {
7pub(super) fn merge_config_into(&mut self, on: &[OnConfig]) -> Result {
8// `with` is mutually exclusive with `into`. So there is nothing to merge here
9 // if `with` is present.
10if self.config.with.is_some() {
11return Ok(());
12 }
1314// For optional named members the target of the `Into` conversion is the type
15 // inside of the `Option<T>`, not the `Option<T>` itself because we generate
16 // a setter that accepts `T` itself. It also makes this logic stable regardless
17 // if `Option<T>` is used or the member of type `T` has `#[builder(default)]` on it.
18let scrutinee = self.underlying_orig_ty();
1920self.config.into = EvalBlanketFlagParam {
21 on,
22 param_name: BlanketParamName::Into,
23 member_config: &self.config,
24 scrutinee,
25 origin: self.origin,
26 }
27 .eval()?;
2829Ok(())
30 }
31}
3233impl PosFnMember {
34pub(crate) fn merge_config_into(&mut self, on: &[OnConfig]) -> Result {
35// Positional members are never optional. Users must always specify them, so there
36 // is no need for us to look into the `Option<T>` generic parameter, because the
37 // `Option<T>` itself is the target of the into conversion, not the `T` inside it.
38let scrutinee = self.ty.orig.as_ref();
3940self.config.into = EvalBlanketFlagParam {
41 on,
42 param_name: BlanketParamName::Into,
43 member_config: &self.config,
44 scrutinee,
45 origin: self.origin,
46 }
47 .eval()?;
4849Ok(())
50 }
5152pub(crate) fn fn_input_param(&self) -> TokenStream {
53let ty = &self.ty.norm;
54let ident = &self.ident;
5556if self.config.into.is_present() {
57quote! { #ident: impl Into<#ty> }
58 } else {
59quote! { #ident: #ty }
60 }
61 }
6263pub(crate) fn conversion(&self) -> Option<TokenStream> {
64if !self.config.into.is_present() {
65return None;
66 }
6768let ident = &self.ident;
6970Some(quote! { Into::into(#ident) })
71 }
72}