fix: incorrect merge logic

This commit is contained in:
naskya 2024-07-16 02:11:16 +09:00
parent 988bfc3380
commit 6fb82e13b9
Signed by: naskya
GPG key ID: 712D413B3A9FED5C

View file

@ -137,7 +137,7 @@ fn derive_impl(input: syn::DeriveInput) -> syn::Result<TokenStream> {
if field.attrs.iter().any(|attr| attr.path().is_ident("relax")) { if field.attrs.iter().any(|attr| attr.path().is_ident("relax")) {
// nested // nested
Ok(quote! { #vis #name: ::std::option::Option<<#ty as ::relax::Relax>::Partial> }) Ok(quote! { #vis #name: ::std::option::Option<<#ty as Relax>::Partial> })
} else { } else {
// not nested // not nested
match get_generic_ty("Option", ty) { match get_generic_ty("Option", ty) {
@ -176,10 +176,25 @@ fn derive_impl(input: syn::DeriveInput) -> syn::Result<TokenStream> {
}) })
}).collect::<syn::Result<Vec<_>>>()?; }).collect::<syn::Result<Vec<_>>>()?;
let merge_fields = fields.iter().map(|field| { let merge_fields = fields.iter().map(|field| -> syn::Result<TokenStream> {
let name = field.ident.as_ref(); let name = field.ident.as_ref();
quote! { #name: self.#name.or(optb.#name) } let nested = field
}); .attrs
.iter()
.any(|attr| attr.path().is_ident("relax"));
Ok(match nested {
false => quote! { #name: self.#name.or(optb.#name) },
true => quote! {
#name: match (self.#name, optb.#name) {
(::std::option::Option::Some(a), ::std::option::Option::None) => ::std::option::Option::Some(a),
(::std::option::Option::None, ::std::option::Option::Some(b)) => ::std::option::Option::Some(b),
(::std::option::Option::None, ::std::option::Option::None) => ::std::option::Option::None,
(::std::option::Option::Some(a), ::std::option::Option::Some(b)) => ::std::option::Option::Some(a.merge(b)),
}
}
})
}).collect::<syn::Result<Vec<_>>>()?;
Ok(quote! { Ok(quote! {
#(#extra_attrs)* #(#extra_attrs)*