diff --git a/instant-xml-macros/src/de.rs b/instant-xml-macros/src/de.rs index d8e1f03..92c1ec5 100644 --- a/instant-xml-macros/src/de.rs +++ b/instant-xml-macros/src/de.rs @@ -57,6 +57,14 @@ fn deserialize_scalar_enum( quote!( impl #impl_generics FromXml<'xml> for #ident #ty_generics #where_clause { + #[inline] + fn matches(id: ::instant_xml::Id<'_>, field: Option<::instant_xml::Id<'_>>) -> bool { + match field { + Some(field) => id == field, + None => false, + } + } + fn deserialize<'cx>( deserializer: &mut ::instant_xml::Deserializer<'cx, 'xml>, into: &mut Option, @@ -123,14 +131,14 @@ fn deserialize_wrapped_enum( } let v_ident = &variant.ident; - variants.extend(quote!(if <#no_lifetime_type as FromXml>::KIND.matches( - id, ::instant_xml::Id { ns: "", name: "" } - ) { - let mut nested = deserializer.nested(data); - let mut value = None; - #no_lifetime_type::deserialize(&mut nested, &mut value)?; - *into = value.map(#ident::#v_ident); - })); + variants.extend( + quote!(if <#no_lifetime_type as FromXml>::matches(id, None) { + let mut nested = deserializer.nested(data); + let mut value = None; + #no_lifetime_type::deserialize(&mut nested, &mut value)?; + *into = value.map(#ident::#v_ident); + }), + ); } let name = meta.tag(); @@ -140,6 +148,14 @@ fn deserialize_wrapped_enum( let (_, ty_generics, where_clause) = input.generics.split_for_impl(); quote!( impl #xml_impl_generics FromXml<'xml> for #ident #ty_generics #where_clause { + #[inline] + fn matches(id: ::instant_xml::Id<'_>, field: Option<::instant_xml::Id<'_>>) -> bool { + match field { + Some(field) => id == field, + None => false, + } + } + fn deserialize<'cx>( deserializer: &mut ::instant_xml::Deserializer<'cx, 'xml>, into: &mut Option, @@ -260,6 +276,11 @@ fn deserialize_struct( quote!( impl #xml_impl_generics FromXml<'xml> for #ident #ty_generics #where_clause { + #[inline] + fn matches(id: ::instant_xml::Id<'_>, field: Option<::instant_xml::Id<'_>>) -> bool { + id == ::instant_xml::Id { ns: #default_namespace, name: #name } + } + fn deserialize<'cx>( deserializer: &mut ::instant_xml::Deserializer<'cx, 'xml>, into: &mut Option, @@ -370,7 +391,7 @@ fn named_field( tokens.branches.extend(quote!(else)); } tokens.branches.extend(quote!( - if <#no_lifetime_type as FromXml>::KIND.matches(id, Id { ns: #ns, name: #field_tag }) + if <#no_lifetime_type as FromXml>::matches(id, Some(Id { ns: #ns, name: #field_tag })) )); tokens.branches.extend(match field_meta.attribute { @@ -512,6 +533,11 @@ fn deserialize_tuple_struct( quote!( impl #xml_impl_generics FromXml<'xml> for #ident #ty_generics #where_clause { + #[inline] + fn matches(id: ::instant_xml::Id<'_>, field: Option<::instant_xml::Id<'_>>) -> bool { + id == ::instant_xml::Id { ns: #default_namespace, name: #name } + } + fn deserialize<'cx>( deserializer: &mut ::instant_xml::Deserializer<'cx, 'xml>, into: &mut Option, @@ -587,6 +613,11 @@ fn deserialize_unit_struct(input: &syn::DeriveInput, meta: &ContainerMeta) -> To quote!( impl #xml_impl_generics FromXml<'xml> for #ident #ty_generics #where_clause { + #[inline] + fn matches(id: ::instant_xml::Id<'_>, field: Option<::instant_xml::Id<'_>>) -> bool { + id == ::instant_xml::Id { ns: #default_namespace, name: #name } + } + fn deserialize<'cx>( deserializer: &mut ::instant_xml::Deserializer<'cx, 'xml>, into: &mut Option, diff --git a/instant-xml/src/impls.rs b/instant-xml/src/impls.rs index 9f27271..32031eb 100644 --- a/instant-xml/src/impls.rs +++ b/instant-xml/src/impls.rs @@ -12,6 +12,14 @@ use crate::{Deserializer, Error, FromXml, Id, Kind, Serializer, ToXml}; struct FromXmlStr(T); impl<'xml, T: FromStr> FromXml<'xml> for FromXmlStr { + #[inline] + fn matches(id: Id<'_>, field: Option>) -> bool { + match field { + Some(field) => id == field, + None => false, + } + } + fn deserialize( deserializer: &mut Deserializer<'_, 'xml>, into: &mut Option, @@ -34,6 +42,14 @@ impl<'xml, T: FromStr> FromXml<'xml> for FromXmlStr { } impl<'xml> FromXml<'xml> for bool { + #[inline] + fn matches(id: Id<'_>, field: Option>) -> bool { + match field { + Some(field) => id == field, + None => false, + } + } + fn deserialize<'cx>( deserializer: &mut Deserializer<'cx, 'xml>, into: &mut Option, @@ -107,6 +123,14 @@ macro_rules! to_xml_for_number { macro_rules! from_xml_for_number { ($typ:ty) => { impl<'xml> FromXml<'xml> for $typ { + #[inline] + fn matches(id: Id<'_>, field: Option>) -> bool { + match field { + Some(field) => id == field, + None => false, + } + } + fn deserialize<'cx>( deserializer: &mut Deserializer<'cx, 'xml>, into: &mut Option, @@ -145,6 +169,14 @@ from_xml_for_number!(f32); from_xml_for_number!(f64); impl<'xml> FromXml<'xml> for char { + #[inline] + fn matches(id: Id<'_>, field: Option>) -> bool { + match field { + Some(field) => id == field, + None => false, + } + } + fn deserialize<'cx>( deserializer: &mut Deserializer<'cx, 'xml>, into: &mut Option, @@ -168,6 +200,14 @@ impl<'xml> FromXml<'xml> for char { } impl<'xml> FromXml<'xml> for String { + #[inline] + fn matches(id: Id<'_>, field: Option>) -> bool { + match field { + Some(field) => id == field, + None => false, + } + } + fn deserialize<'cx>( deserializer: &mut Deserializer<'cx, 'xml>, into: &mut Option, @@ -185,6 +225,14 @@ impl<'xml> FromXml<'xml> for String { } impl<'xml> FromXml<'xml> for &'xml str { + #[inline] + fn matches(id: Id<'_>, field: Option>) -> bool { + match field { + Some(field) => id == field, + None => false, + } + } + fn deserialize<'cx>( deserializer: &mut Deserializer<'cx, 'xml>, into: &mut Option, @@ -214,6 +262,14 @@ where T: ToOwned, T::Owned: FromXml<'xml>, { + #[inline] + fn matches(id: Id<'_>, field: Option>) -> bool { + match field { + Some(field) => id == field, + None => false, + } + } + fn deserialize( deserializer: &mut Deserializer<'_, 'xml>, into: &mut Option, @@ -237,6 +293,11 @@ where } impl<'xml, T: FromXml<'xml>> FromXml<'xml> for Option { + #[inline] + fn matches(id: Id<'_>, field: Option>) -> bool { + T::matches(id, field) + } + fn deserialize<'cx>( deserializer: &mut Deserializer<'cx, 'xml>, into: &mut Option, @@ -446,6 +507,11 @@ pub(crate) fn decode(input: &str) -> Cow<'_, str> { } impl<'xml, T: FromXml<'xml>> FromXml<'xml> for Vec { + #[inline] + fn matches(id: Id<'_>, field: Option>) -> bool { + T::matches(id, field) + } + fn deserialize<'cx>( deserializer: &mut Deserializer<'cx, 'xml>, into: &mut Option, @@ -512,6 +578,14 @@ impl ToXml for DateTime { #[cfg(feature = "chrono")] impl<'xml> FromXml<'xml> for DateTime { + #[inline] + fn matches(id: Id<'_>, field: Option>) -> bool { + match field { + Some(field) => id == field, + None => false, + } + } + fn deserialize<'cx>( deserializer: &mut Deserializer<'cx, 'xml>, into: &mut Option, @@ -534,6 +608,14 @@ impl<'xml> FromXml<'xml> for DateTime { } impl<'xml> FromXml<'xml> for () { + #[inline] + fn matches(id: Id<'_>, field: Option>) -> bool { + match field { + Some(field) => id == field, + None => false, + } + } + fn deserialize<'cx>( _: &mut Deserializer<'cx, 'xml>, into: &mut Option, @@ -558,6 +640,14 @@ impl ToXml for IpAddr { } impl<'xml> FromXml<'xml> for IpAddr { + #[inline] + fn matches(id: Id<'_>, field: Option>) -> bool { + match field { + Some(field) => id == field, + None => false, + } + } + fn deserialize<'cx>( deserializer: &mut Deserializer<'cx, 'xml>, into: &mut Option, diff --git a/instant-xml/src/lib.rs b/instant-xml/src/lib.rs index a2d0721..828d839 100644 --- a/instant-xml/src/lib.rs +++ b/instant-xml/src/lib.rs @@ -36,6 +36,8 @@ impl<'a, T: ToXml + ?Sized> ToXml for &'a T { } pub trait FromXml<'xml>: Sized { + fn matches(id: Id<'_>, field: Option>) -> bool; + fn deserialize<'cx>( deserializer: &mut Deserializer<'cx, 'xml>, into: &mut Option, @@ -132,14 +134,6 @@ impl<'a> Kind<'a> { _ => panic!("expected element kind"), } } - - #[inline] - pub fn matches(&self, id: Id<'_>, field: Id<'_>) -> bool { - match self { - Kind::Scalar => id == field, - Kind::Element(name) => id == *name, - } - } } #[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]