bon_macros/builder/builder_gen/builder_derives/
into.rs1use crate::builder::builder_gen::models::BuilderGenCtx;
2use crate::util::prelude::*;
3
4impl BuilderGenCtx {
5 pub(super) fn derive_into(&self) -> Result<TokenStream> {
6 if let Some(asyncness) = &self.finish_fn.asyncness {
7 bail!(
8 asyncness,
9 "`#[builder(derive(Into))` is not supported for async functions \
10 because `From::from()` method is a synchronous method"
11 )
12 }
13
14 if let Some(unsafety) = &self.finish_fn.unsafety {
15 bail!(
16 unsafety,
17 "`#[builder(derive(Into))` is not supported for unsafe functions \
18 because `From::from()` method is a safe method"
19 )
20 }
21
22 if let Some(arg) = self.finish_fn_args().next() {
23 bail!(
24 &arg.config.finish_fn.span(),
25 "`#[builder(derive(Into))` is incompatible with `#[builder(finish_fn)]` members \
26 because `From::from()` method accepts zero parameters"
27 )
28 }
29
30 let output_ty = match &self.finish_fn.output {
31 syn::ReturnType::Default => bail!(
32 &self.start_fn.ident,
33 "`#[builder(derive(Into))` is not supported for functions with the implicit unit return type; \
34 if you have a use case where it makes sense to implement `From<Builder> for ()`, \
35 please open an issue, and in the meantime annotate the function return type explicitly \
36 with `-> ()`"
37 ),
38 syn::ReturnType::Type(_, output_ty) => output_ty.as_ref(),
39 };
40
41 let state_mod = &self.state_mod.ident;
42 let generics_decl = &self.generics.decl_without_defaults;
43 let generic_args = &self.generics.args;
44 let where_clause = &self.generics.where_clause;
45 let builder_ident = &self.builder_type.ident;
46 let state_var = &self.state_var;
47 let finish_fn_ident = &self.finish_fn.ident;
48
49 let builder_ty = quote! {
50 #builder_ident<#(#generic_args,)* #state_var>
51 };
52
53 let tokens = quote! {
54 #[automatically_derived]
55 impl<
56 #(#generics_decl,)*
57 #state_var: #state_mod::IsComplete
58 >
59 ::core::convert::From<#builder_ty> for #output_ty
60 #where_clause
61 {
62 fn from(builder: #builder_ty) -> Self {
63 #builder_ident::#finish_fn_ident(builder)
64 }
65 }
66 };
67
68 Ok(tokens)
69 }
70}