bon_macros/builder/builder_gen/
start_fn.rs
1use crate::util::prelude::*;
2
3impl super::BuilderGenCtx {
4 pub(super) fn start_fn(&self) -> syn::ItemFn {
5 let builder_ident = &self.builder_type.ident;
6 let docs = &self.start_fn.docs;
7 let vis = &self.start_fn.vis;
8
9 let start_fn_ident = &self.start_fn.ident;
10
11 let generics = self.start_fn.generics.as_ref().unwrap_or(&self.generics);
19
20 let generics_decl = &generics.decl_without_defaults;
21 let where_clause = &generics.where_clause;
22 let generic_args = &self.generics.args;
23
24 let receiver = self.receiver();
25
26 let receiver_field_init = receiver.map(|receiver| {
27 let self_token = &receiver.with_self_keyword.self_token;
28 quote! {
29 __unsafe_private_receiver: #self_token,
30 }
31 });
32
33 let receiver = receiver.map(|receiver| {
34 let mut receiver = receiver.with_self_keyword.clone();
35
36 if receiver.reference.is_none() {
37 receiver.mutability = None;
38 }
39
40 quote! { #receiver, }
41 });
42
43 let start_fn_params = self
44 .start_fn_args()
45 .map(|member| member.base.fn_input_param());
46
47 let start_fn_vars = self.start_fn_args().filter_map(|member| {
52 let ident = &member.base.ident;
53 let ty = &member.base.ty.orig;
54 let conversion = member.base.conversion()?;
55
56 Some(quote! {
57 let #ident: #ty = #conversion;
58 })
59 });
60
61 let mut start_fn_args = self.start_fn_args().peekable();
62
63 let start_fn_args_field_init = start_fn_args.peek().is_some().then(|| {
64 let idents = start_fn_args.map(|member| &member.base.ident);
65 quote! {
66 __unsafe_private_start_fn_args: (#(#idents,)*),
67 }
68 });
69
70 let custom_fields_vars = self.custom_fields().map(|field| {
74 let ident = &field.ident;
75 let ty = &field.norm_ty;
76 let init = field
77 .init
78 .as_ref()
79 .map(|init| quote! { (|| #init)() })
80 .unwrap_or_else(|| quote! { ::core::default::Default::default() });
81
82 quote! {
83 let #ident: #ty = #init;
84 }
85 });
86
87 let custom_fields_idents = self.custom_fields().map(|field| &field.ident);
88
89 let ide_hints = self.ide_hints();
90
91 let named_members_field_init = if self.named_members().take(13).count() <= 12 {
95 quote!(::core::default::Default::default())
96 } else {
97 let none = format_ident!("None");
98 let nones = self.named_members().map(|_| &none);
99 quote! {
100 (#(#nones,)*)
101 }
102 };
103
104 syn::parse_quote! {
105 #(#docs)*
106 #[inline(always)]
107 #[allow(
108 clippy::inline_always,
110 clippy::use_self,
112 clippy::missing_const_for_fn,
115 )]
116 #vis fn #start_fn_ident< #(#generics_decl),* >(
117 #receiver
118 #(#start_fn_params,)*
119 ) -> #builder_ident< #(#generic_args,)* >
120 #where_clause
121 {
122 #ide_hints
123 #( #start_fn_vars )*
124 #( #custom_fields_vars )*
125
126 #builder_ident {
127 __unsafe_private_phantom: ::core::marker::PhantomData,
128 #( #custom_fields_idents, )*
129 #receiver_field_init
130 #start_fn_args_field_init
131 __unsafe_private_named: #named_members_field_init,
132 }
133 }
134 }
135 }
136}