Fix use of lifetimes in fields of transparent structs

This commit is contained in:
Dirkjan Ochtman 2023-02-28 16:31:50 +01:00
parent a5795b9b2d
commit f51e6ae063
2 changed files with 19 additions and 15 deletions

View File

@ -437,11 +437,13 @@ fn deserialize_inline_struct(
let field_ty = data.no_lifetime_type; let field_ty = data.no_lifetime_type;
matches.extend(quote!( matches.extend(quote!(
#field_ty::matches(id, None) <#field_ty as FromXml<'xml>>::matches(id, None)
)); ));
let field_name = &field.ident; let field_name = &field.ident;
acc_field_defs.extend(quote!(#field_name: <#field_ty as FromXml<'xml>>::Accumulator,)); let field_ty_with_lifetime = &field.ty;
acc_field_defs
.extend(quote!(#field_name: <#field_ty_with_lifetime as FromXml<'xml>>::Accumulator,));
let field_str = format!("{}::{}", input.ident, data.field_name); let field_str = format!("{}::{}", input.ident, data.field_name);
acc_field_inits.extend(quote!(#field_name: self.#field_name.try_done(#field_str)?,)); acc_field_inits.extend(quote!(#field_name: self.#field_name.try_done(#field_str)?,));
acc_field_defaults.extend(quote!(#field_name: Default::default(),)); acc_field_defaults.extend(quote!(#field_name: Default::default(),));
@ -450,11 +452,13 @@ fn deserialize_inline_struct(
deserialize.extend(quote!(else)); deserialize.extend(quote!(else));
} }
if let Some(with) = data.deserialize_with { if let Some(with) = data.deserialize_with {
deserialize.extend(quote!(if #field_ty::matches(current, None) { deserialize.extend(
#with(&mut into.#field_name, #field_str, deserializer)?; quote!(if <#field_ty as FromXml<'xml>>::matches(current, None) {
})); #with(&mut into.#field_name, #field_str, deserializer)?;
}),
);
} else { } else {
deserialize.extend(quote!(if #field_ty::matches(current, None) { deserialize.extend(quote!(if <#field_ty as FromXml<'xml>>::matches(current, None) {
match <#field_ty as FromXml>::KIND { match <#field_ty as FromXml>::KIND {
Kind::Element => { Kind::Element => {
<#field_ty>::deserialize(&mut into.#field_name, #field_str, deserializer)?; <#field_ty>::deserialize(&mut into.#field_name, #field_str, deserializer)?;
@ -505,7 +509,7 @@ fn deserialize_inline_struct(
} }
impl #xml_impl_generics ::instant_xml::Accumulate<#ident #ty_generics> for #accumulator #xml_ty_generics #where_clause { impl #xml_impl_generics ::instant_xml::Accumulate<#ident #ty_generics> for #accumulator #xml_ty_generics #where_clause {
fn try_done(self, field: &'static str) -> Result<#ident #ty_generics, ::instant_xml::Error> { fn try_done(self, _: &'static str) -> Result<#ident #ty_generics, ::instant_xml::Error> {
Ok(#ident { Ok(#ident {
#acc_field_inits #acc_field_inits
}) })

View File

@ -1,17 +1,19 @@
use std::borrow::Cow;
use similar_asserts::assert_eq; use similar_asserts::assert_eq;
use instant_xml::{from_str, to_string, Error, FromXml, ToXml}; use instant_xml::{from_str, to_string, Error, FromXml, ToXml};
#[derive(Debug, Eq, FromXml, PartialEq, ToXml)] #[derive(Debug, Eq, FromXml, PartialEq, ToXml)]
struct Wrapper { struct Wrapper {
inline: Inline, inline: Inline<'static>,
} }
#[derive(Debug, Eq, FromXml, PartialEq, ToXml)] #[derive(Debug, Eq, FromXml, PartialEq, ToXml)]
#[xml(transparent)] #[xml(transparent)]
struct Inline { struct Inline<'a> {
foo: Foo, foo: Foo,
bar: Bar, bar: Bar<'a>,
} }
#[derive(Debug, Eq, FromXml, PartialEq, ToXml)] #[derive(Debug, Eq, FromXml, PartialEq, ToXml)]
@ -20,8 +22,8 @@ struct Foo {
} }
#[derive(Debug, Eq, FromXml, PartialEq, ToXml)] #[derive(Debug, Eq, FromXml, PartialEq, ToXml)]
struct Bar { struct Bar<'a> {
s: String, s: Cow<'a, str>,
} }
#[test] #[test]
@ -29,9 +31,7 @@ fn inline() {
let v = Wrapper { let v = Wrapper {
inline: Inline { inline: Inline {
foo: Foo { i: 42 }, foo: Foo { i: 42 },
bar: Bar { bar: Bar { s: "hello".into() },
s: "hello".to_string(),
},
}, },
}; };