1
0
mirror of https://gitlab.com/xmpp-rs/xmpp-rs.git synced 2024-06-18 13:45:57 +02:00

parsers-core, parsers-macros: Remove XmlCollection trait

This can be represented appropriately using Extend<T>, IntoIterator and
Default from the standard library.
This commit is contained in:
Jonas Schäfer 2024-03-23 17:36:19 +01:00
parent 2b2bff1efa
commit e0b528ceb7
2 changed files with 27 additions and 35 deletions

View File

@ -218,7 +218,10 @@ The following field kinds are available:
attribute.
- `children`: Extract zero or more entire child elements. The field type must
implement [`XmlCollection`].
implement [`Default`][`std::default::Default`],
[`Extend<T>`][`std::iter::Extend`] and
[`IntoIterator<Item = T>`][`std::iter::IntoIterator`], where `T`
implements [`FromXml`] (and [`IntoXml`] for [`IntoXml`]).
The namespace and name to match are determined by the field type, thus it
is not allowed to specify them here.
@ -428,26 +431,6 @@ impl IntoText for String {
}
}
/// TODO: remove this
pub trait XmlCollection {
/// TODO: remove this
fn new_empty() -> Self;
/// TODO: remove this
fn try_append(&mut self, element: minidom::Element) -> Result<(), error::Error>;
}
impl<T: TryFrom<minidom::Element, Error = error::Error>> XmlCollection for Vec<T> {
fn new_empty() -> Self {
Self::new()
}
fn try_append(&mut self, element: minidom::Element) -> Result<(), error::Error> {
self.push(T::try_from(element)?);
Ok(())
}
}
/// Specify handling for complex data types mapped to XML.
///
/// Implementing this trait allows a value to be used in collections in the

View File

@ -458,20 +458,29 @@ impl ChildField {
..FieldParsePart::default()
})
}
None => Ok(FieldParsePart {
tempinit: quote! {
let mut #tempname = <#ty as ::xmpp_parsers_core::XmlCollection>::new_empty();
},
childiter: quote! {
let mut residual = match <#ty as ::xmpp_parsers_core::XmlCollection>::try_append(&mut #tempname, residual) {
Ok(()) => continue,
Err(::xmpp_parsers_core::error::Error::TypeMismatch(_, _, e)) => e,
Err(other) => return Err(other),
};
},
value: quote! { #tempname },
..FieldParsePart::default()
}),
None => {
let item_ty: Type = syn::parse2(quote! {
<#ty as IntoIterator>::Item
})
.expect("failed to construct item type");
Ok(FieldParsePart {
tempinit: quote! {
let mut #tempname = <#ty as std::default::Default>::default();
},
childiter: quote! {
let mut residual = match <#item_ty as ::xmpp_parsers_core::FromXml>::from_tree(residual) {
Ok(item) => {
<#ty as ::std::iter::Extend<#item_ty>>::extend(&mut #tempname, [item]);
continue;
},
Err(::xmpp_parsers_core::error::Error::TypeMismatch(_, _, e)) => e,
Err(other) => return Err(other),
};
},
value: quote! { #tempname },
..FieldParsePart::default()
})
}
},
}
}