From a08d9f1a1afa6ec11bcb99e29b030b1d3a44b63f Mon Sep 17 00:00:00 2001 From: Mica White Date: Thu, 24 Sep 2026 20:59:43 -0400 Subject: Support base expressions --- src/lib.rs | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/lib.rs b/src/lib.rs index 314f813..8024048 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -293,6 +293,14 @@ pub fn derive_builder(input: TokenStream) -> TokenStream { #builder_macro + impl core::convert::From<#struct_name> for #builder_name<#(#trues),*> { + fn from(s: #struct_name) -> Self { + Self { + #(#field_names: Some(s.#field_names),)* + } + } + } + impl<#(const #const_generics: bool),*> core::default::Default for #builder_name<#(#const_generics),*> { fn default() -> Self { Self { @@ -305,6 +313,10 @@ pub fn derive_builder(input: TokenStream) -> TokenStream { #builder_visibility fn builder() -> #builder_name<#(#falses),*> { #builder_name::default() } + + #builder_visibility fn into_builder(self) -> #builder_name<#(#trues),*> { + #builder_name::from(self) + } } impl<#(const #const_generics: bool),*> #builder_name<#(#const_generics),*> { @@ -360,17 +372,28 @@ pub fn derive_builder(input: TokenStream) -> TokenStream { pub fn build(input: TokenStream) -> TokenStream { let structure = parse_macro_input!(input as ExprStruct); let struct_name = &structure.path; + let base = &structure.rest; let field_names = structure.fields.iter().map(|field| &field.member); let field_values = structure.fields.iter().map(|field| &field.expr); - quote! { - #struct_name - ::builder() - #(.#field_names(#field_values))* - .build() + if let Some(base) = base { + quote! { + #base + .into_builder() + #(.#field_names(#field_values))* + .build() + } + .into() + } else { + quote! { + #struct_name + ::builder() + #(.#field_names(#field_values))* + .build() + } + .into() } - .into() } /// Creates a declarative macro to construct a type that derives [`Builder`] -- cgit v1.3.1