diff --git a/crates/refineable/derive_refineable/src/derive_refineable.rs b/crates/refineable/derive_refineable/src/derive_refineable.rs index 1462b48078..ed233e1b0d 100644 --- a/crates/refineable/derive_refineable/src/derive_refineable.rs +++ b/crates/refineable/derive_refineable/src/derive_refineable.rs @@ -157,7 +157,7 @@ pub fn derive_refineable(input: TokenStream) -> TokenStream { }) .collect(); - let refinement_refined_assignments: Vec = fields + let refinement_refined_assigments: Vec = fields .iter() .map(|field| { let name = &field.ident; @@ -169,14 +169,37 @@ pub fn derive_refineable(input: TokenStream) -> TokenStream { } } else { quote! { - if refinement.#name.is_some() { - self.#name = refinement.#name; + if let Some(value) = refinement.#name { + self.#name = Some(value); } } } }) .collect(); + let from_refinement_assigments: Vec = fields + .iter() + .map(|field| { + let name = &field.ident; + let is_refineable = is_refineable_field(field); + let is_optional = is_optional_field(field); + + if is_refineable { + quote! { + #name: value.#name.into(), + } + } else if is_optional { + quote! { + #name: value.#name.map(|v| v.into()), + } + } else { + quote! { + #name: value.#name.map(|v| v.into()).unwrap_or_default(), + } + } + }) + .collect(); + let debug_impl = if impl_debug_on_refinement { let refinement_field_debugs: Vec = fields .iter() @@ -243,11 +266,21 @@ pub fn derive_refineable(input: TokenStream) -> TokenStream { } fn refined(mut self, refinement: Self::Refinement) -> Self { - #( #refinement_refined_assignments )* + #( #refinement_refined_assigments )* self } } + impl #impl_generics From<#refinement_ident #ty_generics> for #ident #ty_generics + #where_clause + { + fn from(value: #refinement_ident #ty_generics) -> Self { + Self { + #( #from_refinement_assigments )* + } + } + } + impl #impl_generics ::core::default::Default for #refinement_ident #ty_generics #where_clause { @@ -273,7 +306,6 @@ pub fn derive_refineable(input: TokenStream) -> TokenStream { #debug_impl }; - gen.into() }