mirror of
https://gitlab.com/xmpp-rs/xmpp-rs.git
synced 2024-06-09 09:44:03 +02:00
parsers-core, parsers-macros: Remove XmlDataCollection trait
This can be represented appropriately using Extend<T>, IntoIterator and Default from the standard library. We keep the XmlDataItem trait for flexibility though.
This commit is contained in:
parent
e0b528ceb7
commit
f1dc7594e0
|
@ -13,8 +13,6 @@ a full reference on the supported attributes.
|
|||
[^serde-note]: Though it should be said that you can combine serde and this
|
||||
crate on the same struct, no problem with that!
|
||||
*/
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
pub mod error;
|
||||
mod text;
|
||||
|
||||
|
@ -213,9 +211,14 @@ The following field kinds are available:
|
|||
|
||||
- More than one clause inside `extract(..)` are allowed.
|
||||
- More than one matching child is allowed
|
||||
- The field type must implement `XmlDataCollection<T>`, where T is a tuple
|
||||
of N strings, where N is the number of clauses in the `extract(..)`
|
||||
attribute.
|
||||
- The field type must implement [`Default`][`std::default::Default`],
|
||||
[`Extend<T>`][`std::iter::Extend`] and
|
||||
[`IntoIterator<Item = T>`][`std::iter::IntoIterator`], where `T`
|
||||
implements [`XmlDataItem<U>`][`XmlDataItem`].
|
||||
|
||||
`U`, in turn, must be a tuple type matching the types provided by the
|
||||
extracted parts. Text and attributes map to [`String`], `elements` maps
|
||||
to `Vec<minidom::Element>`.
|
||||
|
||||
- `children`: Extract zero or more entire child elements. The field type must
|
||||
implement [`Default`][`std::default::Default`],
|
||||
|
@ -473,59 +476,3 @@ impl<A: FromText + IntoText, B: FromText + IntoText> XmlDataItem<(String, String
|
|||
(self.0.into_text(), self.1.into_text())
|
||||
}
|
||||
}
|
||||
|
||||
/// TODO: remove this
|
||||
pub trait XmlDataCollection {
|
||||
/// TODO: remove this
|
||||
type Input;
|
||||
/// TODO: remove this
|
||||
type Item: XmlDataItem<Self::Input>;
|
||||
/// TODO: remove this
|
||||
type IntoIter: Iterator<Item = Self::Item>;
|
||||
|
||||
/// TODO: remove this
|
||||
fn new_empty() -> Self;
|
||||
/// TODO: remove this
|
||||
fn append_data(&mut self, item: Self::Item);
|
||||
/// TODO: remove this
|
||||
fn into_data_iterator(self) -> Self::IntoIter;
|
||||
}
|
||||
|
||||
impl<T: XmlDataItem<String>> XmlDataCollection for Vec<T> {
|
||||
type Input = String;
|
||||
type Item = T;
|
||||
type IntoIter = std::vec::IntoIter<T>;
|
||||
|
||||
fn new_empty() -> Self {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
fn append_data(&mut self, item: Self::Item) {
|
||||
self.push(item);
|
||||
}
|
||||
|
||||
fn into_data_iterator(self) -> Self::IntoIter {
|
||||
self.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Ord, V> XmlDataCollection for BTreeMap<K, V>
|
||||
where
|
||||
(K, V): XmlDataItem<(String, String)>,
|
||||
{
|
||||
type Input = (String, String);
|
||||
type Item = (K, V);
|
||||
type IntoIter = std::collections::btree_map::IntoIter<K, V>;
|
||||
|
||||
fn new_empty() -> Self {
|
||||
BTreeMap::new()
|
||||
}
|
||||
|
||||
fn append_data(&mut self, item: Self::Item) {
|
||||
self.insert(item.0, item.1);
|
||||
}
|
||||
|
||||
fn into_data_iterator(self) -> Self::IntoIter {
|
||||
self.into_iter()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -440,15 +440,19 @@ impl ChildField {
|
|||
Some(extract) => {
|
||||
let extract =
|
||||
extract.build_extract(&Ident::new("residual", Span::call_site()), 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 ::xmpp_parsers_core::XmlDataCollection>::new_empty();
|
||||
let mut #tempname = <#ty as ::std::default::Default>::default();
|
||||
},
|
||||
childiter: quote! {
|
||||
residual = match #extract {
|
||||
Ok(v) => {
|
||||
let v = <<#ty as ::xmpp_parsers_core::XmlDataCollection>::Item as ::xmpp_parsers_core::XmlDataItem<<#ty as ::xmpp_parsers_core::XmlDataCollection>::Input>>::from_raw(v)?;
|
||||
<#ty as ::xmpp_parsers_core::XmlDataCollection>::append_data(&mut #tempname, v);
|
||||
let v = <#item_ty as ::xmpp_parsers_core::XmlDataItem<_>>::from_raw(v)?;
|
||||
<#ty as ::std::iter::Extend<#item_ty>>::extend(&mut #tempname, [v]);
|
||||
continue;
|
||||
},
|
||||
Err(residual) => residual,
|
||||
|
@ -521,10 +525,14 @@ impl ChildField {
|
|||
}),
|
||||
None,
|
||||
)?;
|
||||
let item_ty: Type = syn::parse2(quote! {
|
||||
<#ty as IntoIterator>::Item
|
||||
})
|
||||
.expect("failed to construct item type");
|
||||
Ok(quote! {
|
||||
builder.append_all(
|
||||
#ident.into_iter().filter_map(|item| {
|
||||
let data = <<#ty as ::xmpp_parsers_core::XmlDataCollection>::Item as ::xmpp_parsers_core::XmlDataItem<<#ty as ::xmpp_parsers_core::XmlDataCollection>::Input>>::into_raw(item);
|
||||
let data = <#item_ty as ::xmpp_parsers_core::XmlDataItem<_>>::into_raw(item);
|
||||
#assemble
|
||||
})
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue
Block a user