Implement matches() directly on FromXml

This commit is contained in:
Dirkjan Ochtman 2022-11-29 16:02:43 +01:00
parent 9b2cd415af
commit 6b3fa93f69
3 changed files with 132 additions and 17 deletions

View File

@ -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<Self>,
@ -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: "" }
) {
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<Self>,
@ -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<Self>,
@ -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<Self>,
@ -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<Self>,

View File

@ -12,6 +12,14 @@ use crate::{Deserializer, Error, FromXml, Id, Kind, Serializer, ToXml};
struct FromXmlStr<T: FromStr>(T);
impl<'xml, T: FromStr> FromXml<'xml> for FromXmlStr<T> {
#[inline]
fn matches(id: Id<'_>, field: Option<Id<'_>>) -> bool {
match field {
Some(field) => id == field,
None => false,
}
}
fn deserialize(
deserializer: &mut Deserializer<'_, 'xml>,
into: &mut Option<Self>,
@ -34,6 +42,14 @@ impl<'xml, T: FromStr> FromXml<'xml> for FromXmlStr<T> {
}
impl<'xml> FromXml<'xml> for bool {
#[inline]
fn matches(id: Id<'_>, field: Option<Id<'_>>) -> bool {
match field {
Some(field) => id == field,
None => false,
}
}
fn deserialize<'cx>(
deserializer: &mut Deserializer<'cx, 'xml>,
into: &mut Option<Self>,
@ -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<Id<'_>>) -> bool {
match field {
Some(field) => id == field,
None => false,
}
}
fn deserialize<'cx>(
deserializer: &mut Deserializer<'cx, 'xml>,
into: &mut Option<Self>,
@ -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<Id<'_>>) -> bool {
match field {
Some(field) => id == field,
None => false,
}
}
fn deserialize<'cx>(
deserializer: &mut Deserializer<'cx, 'xml>,
into: &mut Option<Self>,
@ -168,6 +200,14 @@ impl<'xml> FromXml<'xml> for char {
}
impl<'xml> FromXml<'xml> for String {
#[inline]
fn matches(id: Id<'_>, field: Option<Id<'_>>) -> bool {
match field {
Some(field) => id == field,
None => false,
}
}
fn deserialize<'cx>(
deserializer: &mut Deserializer<'cx, 'xml>,
into: &mut Option<Self>,
@ -185,6 +225,14 @@ impl<'xml> FromXml<'xml> for String {
}
impl<'xml> FromXml<'xml> for &'xml str {
#[inline]
fn matches(id: Id<'_>, field: Option<Id<'_>>) -> bool {
match field {
Some(field) => id == field,
None => false,
}
}
fn deserialize<'cx>(
deserializer: &mut Deserializer<'cx, 'xml>,
into: &mut Option<Self>,
@ -214,6 +262,14 @@ where
T: ToOwned,
T::Owned: FromXml<'xml>,
{
#[inline]
fn matches(id: Id<'_>, field: Option<Id<'_>>) -> bool {
match field {
Some(field) => id == field,
None => false,
}
}
fn deserialize(
deserializer: &mut Deserializer<'_, 'xml>,
into: &mut Option<Self>,
@ -237,6 +293,11 @@ where
}
impl<'xml, T: FromXml<'xml>> FromXml<'xml> for Option<T> {
#[inline]
fn matches(id: Id<'_>, field: Option<Id<'_>>) -> bool {
T::matches(id, field)
}
fn deserialize<'cx>(
deserializer: &mut Deserializer<'cx, 'xml>,
into: &mut Option<Self>,
@ -446,6 +507,11 @@ pub(crate) fn decode(input: &str) -> Cow<'_, str> {
}
impl<'xml, T: FromXml<'xml>> FromXml<'xml> for Vec<T> {
#[inline]
fn matches(id: Id<'_>, field: Option<Id<'_>>) -> bool {
T::matches(id, field)
}
fn deserialize<'cx>(
deserializer: &mut Deserializer<'cx, 'xml>,
into: &mut Option<Self>,
@ -512,6 +578,14 @@ impl ToXml for DateTime<Utc> {
#[cfg(feature = "chrono")]
impl<'xml> FromXml<'xml> for DateTime<Utc> {
#[inline]
fn matches(id: Id<'_>, field: Option<Id<'_>>) -> bool {
match field {
Some(field) => id == field,
None => false,
}
}
fn deserialize<'cx>(
deserializer: &mut Deserializer<'cx, 'xml>,
into: &mut Option<Self>,
@ -534,6 +608,14 @@ impl<'xml> FromXml<'xml> for DateTime<Utc> {
}
impl<'xml> FromXml<'xml> for () {
#[inline]
fn matches(id: Id<'_>, field: Option<Id<'_>>) -> bool {
match field {
Some(field) => id == field,
None => false,
}
}
fn deserialize<'cx>(
_: &mut Deserializer<'cx, 'xml>,
into: &mut Option<Self>,
@ -558,6 +640,14 @@ impl ToXml for IpAddr {
}
impl<'xml> FromXml<'xml> for IpAddr {
#[inline]
fn matches(id: Id<'_>, field: Option<Id<'_>>) -> bool {
match field {
Some(field) => id == field,
None => false,
}
}
fn deserialize<'cx>(
deserializer: &mut Deserializer<'cx, 'xml>,
into: &mut Option<Self>,

View File

@ -36,6 +36,8 @@ impl<'a, T: ToXml + ?Sized> ToXml for &'a T {
}
pub trait FromXml<'xml>: Sized {
fn matches(id: Id<'_>, field: Option<Id<'_>>) -> bool;
fn deserialize<'cx>(
deserializer: &mut Deserializer<'cx, 'xml>,
into: &mut Option<Self>,
@ -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)]