pubsub::event: Use the new helper macros to simplify parsing.

This commit is contained in:
Emmanuel Gil Peyrot 2017-10-10 19:27:29 +01:00
parent 5f6f6a5e91
commit e1477f146b

View file

@ -25,6 +25,26 @@ pub struct Item {
publisher: Option<Jid>, publisher: Option<Jid>,
} }
impl TryFrom<Element> for Item {
type Err = Error;
fn try_from(elem: Element) -> Result<Item, Error> {
check_self!(elem, "item", ns::PUBSUB_EVENT);
check_no_unknown_attributes!(elem, "item", ["id", "node", "publisher"]);
let mut payloads = elem.children().cloned().collect::<Vec<_>>();
let payload = payloads.pop();
if !payloads.is_empty() {
return Err(Error::ParseError("More than a single payload in item element."));
}
Ok(Item {
payload,
id: get_attr!(elem, "id", optional),
node: get_attr!(elem, "node", optional),
publisher: get_attr!(elem, "publisher", optional),
})
}
}
impl From<Item> for Element { impl From<Item> for Element {
fn from(item: Item) -> Element { fn from(item: Item) -> Element {
Element::builder("item") Element::builder("item")
@ -92,32 +112,15 @@ fn parse_items(elem: Element, node: String) -> Result<PubSubEvent, Error> {
Some(false) => (), Some(false) => (),
Some(true) => return Err(Error::ParseError("Mix of item and retract in items element.")), Some(true) => return Err(Error::ParseError("Mix of item and retract in items element.")),
} }
let mut payloads = child.children().cloned().collect::<Vec<_>>(); items.push(Item::try_from(child.clone())?);
let payload = payloads.pop();
if !payloads.is_empty() {
return Err(Error::ParseError("More than a single payload in item element."));
}
let item = Item {
payload,
id: get_attr!(child, "id", optional),
node: get_attr!(child, "node", optional),
publisher: get_attr!(child, "publisher", optional),
};
items.push(item);
} else if child.is("retract", ns::PUBSUB_EVENT) { } else if child.is("retract", ns::PUBSUB_EVENT) {
match is_retract { match is_retract {
None => is_retract = Some(true), None => is_retract = Some(true),
Some(true) => (), Some(true) => (),
Some(false) => return Err(Error::ParseError("Mix of item and retract in items element.")), Some(false) => return Err(Error::ParseError("Mix of item and retract in items element.")),
} }
for _ in child.children() { check_no_children!(child, "retract");
return Err(Error::ParseError("Unknown child in retract element.")); check_no_unknown_attributes!(child, "retract", ["id"]);
}
for (attr, _) in child.attrs() {
if attr != "id" {
return Err(Error::ParseError("Unknown attribute in retract element."));
}
}
let id = get_attr!(child, "id", required); let id = get_attr!(child, "id", required);
retracts.push(id); retracts.push(id);
} else { } else {
@ -135,21 +138,11 @@ impl TryFrom<Element> for PubSubEvent {
type Err = Error; type Err = Error;
fn try_from(elem: Element) -> Result<PubSubEvent, Error> { fn try_from(elem: Element) -> Result<PubSubEvent, Error> {
if !elem.is("event", ns::PUBSUB_EVENT) { check_self!(elem, "event", ns::PUBSUB_EVENT);
return Err(Error::ParseError("This is not an event element.")); check_no_unknown_attributes!(elem, "event", []);
}
for _ in elem.attrs() {
return Err(Error::ParseError("Unknown attribute in event element."));
}
let mut payload = None; let mut payload = None;
for child in elem.children() { for child in elem.children() {
/*
for (attr, _) in child.attrs() {
if attr != "node" {
return Err(Error::ParseError("Unknown attribute in items element."));
}
}
*/
let node = get_attr!(child, "node", required); let node = get_attr!(child, "node", required);
if child.is("configuration", ns::PUBSUB_EVENT) { if child.is("configuration", ns::PUBSUB_EVENT) {
let mut payloads = child.children().cloned().collect::<Vec<_>>(); let mut payloads = child.children().cloned().collect::<Vec<_>>();