mirror of
https://gitlab.com/xmpp-rs/xmpp-rs.git
synced 2024-07-12 22:21:53 +00:00
roster: Simplify parsing of Item.
This commit is contained in:
parent
80a2f425e2
commit
42a3e42533
2 changed files with 35 additions and 56 deletions
|
@ -8,6 +8,13 @@ macro_rules! get_attr {
|
||||||
($elem:ident, $attr:tt, $type:tt) => (
|
($elem:ident, $attr:tt, $type:tt) => (
|
||||||
get_attr!($elem, $attr, $type, value, value.parse()?)
|
get_attr!($elem, $attr, $type, value, value.parse()?)
|
||||||
);
|
);
|
||||||
|
($elem:ident, $attr:tt, optional_empty, $value:ident, $func:expr) => (
|
||||||
|
match $elem.attr($attr) {
|
||||||
|
Some("") => None,
|
||||||
|
Some($value) => Some($func),
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
);
|
||||||
($elem:ident, $attr:tt, optional, $value:ident, $func:expr) => (
|
($elem:ident, $attr:tt, optional, $value:ident, $func:expr) => (
|
||||||
match $elem.attr($attr) {
|
match $elem.attr($attr) {
|
||||||
Some($value) => Some($func),
|
Some($value) => Some($func),
|
||||||
|
@ -277,6 +284,16 @@ macro_rules! generate_elem_id {
|
||||||
Ok($elem(String::from(s)))
|
Ok($elem(String::from(s)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl TryFrom<Element> for $elem {
|
||||||
|
type Err = Error;
|
||||||
|
fn try_from(elem: Element) -> Result<$elem, Error> {
|
||||||
|
check_self!(elem, $name, $ns);
|
||||||
|
check_no_children!(elem, $name);
|
||||||
|
check_no_attributes!(elem, $name);
|
||||||
|
// TODO: add a way to parse that differently when needed.
|
||||||
|
Ok($elem(elem.text()))
|
||||||
|
}
|
||||||
|
}
|
||||||
impl From<$elem> for Element {
|
impl From<$elem> for Element {
|
||||||
fn from(elem: $elem) -> Element {
|
fn from(elem: $elem) -> Element {
|
||||||
Element::builder($name)
|
Element::builder($name)
|
||||||
|
|
|
@ -23,64 +23,26 @@ generate_attribute!(Subscription, "subscription", {
|
||||||
Remove => "remove",
|
Remove => "remove",
|
||||||
}, Default = None);
|
}, Default = None);
|
||||||
|
|
||||||
/// Contact from the user’s contact list.
|
generate_element_with_children!(
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
/// Contact from the user’s contact list.
|
||||||
pub struct Item {
|
#[derive(PartialEq)]
|
||||||
|
Item, "item", ns::ROSTER,
|
||||||
|
attributes: [
|
||||||
/// JID of this contact.
|
/// JID of this contact.
|
||||||
pub jid: Jid,
|
jid: Jid = "jid" => required,
|
||||||
|
|
||||||
/// Name of this contact.
|
/// Name of this contact.
|
||||||
pub name: Option<String>,
|
name: Option<String> = "name" => optional_empty,
|
||||||
|
|
||||||
/// Subscription status of this contact.
|
/// Subscription status of this contact.
|
||||||
pub subscription: Subscription,
|
subscription: Subscription = "subscription" => default
|
||||||
|
],
|
||||||
|
|
||||||
|
children: [
|
||||||
/// Groups this contact is part of.
|
/// Groups this contact is part of.
|
||||||
pub groups: Vec<Group>,
|
groups: Vec<Group> = ("group", ns::ROSTER) => Group
|
||||||
}
|
]
|
||||||
|
);
|
||||||
impl TryFrom<Element> for Item {
|
|
||||||
type Err = Error;
|
|
||||||
|
|
||||||
fn try_from(elem: Element) -> Result<Item, Error> {
|
|
||||||
if !elem.is("item", ns::ROSTER) {
|
|
||||||
return Err(Error::ParseError("This is not a roster item element."));
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut item = Item {
|
|
||||||
jid: get_attr!(elem, "jid", required),
|
|
||||||
name: get_attr!(elem, "name", optional).and_then(|name| if name == "" { None } else { Some(name) }),
|
|
||||||
subscription: get_attr!(elem, "subscription", default),
|
|
||||||
groups: vec!(),
|
|
||||||
};
|
|
||||||
for child in elem.children() {
|
|
||||||
if !child.is("group", ns::ROSTER) {
|
|
||||||
return Err(Error::ParseError("Unknown element in roster item element."));
|
|
||||||
}
|
|
||||||
for _ in child.children() {
|
|
||||||
return Err(Error::ParseError("Roster item group can’t have children."));
|
|
||||||
}
|
|
||||||
for _ in child.attrs() {
|
|
||||||
return Err(Error::ParseError("Roster item group can’t have attributes."));
|
|
||||||
}
|
|
||||||
let group = Group(child.text());
|
|
||||||
item.groups.push(group);
|
|
||||||
}
|
|
||||||
Ok(item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Item> for Element {
|
|
||||||
fn from(item: Item) -> Element {
|
|
||||||
Element::builder("item")
|
|
||||||
.ns(ns::ROSTER)
|
|
||||||
.attr("jid", item.jid)
|
|
||||||
.attr("name", item.name)
|
|
||||||
.attr("subscription", item.subscription)
|
|
||||||
.append(item.groups)
|
|
||||||
.build()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
generate_element_with_children!(
|
generate_element_with_children!(
|
||||||
/// The contact list of the user.
|
/// The contact list of the user.
|
||||||
|
@ -258,6 +220,6 @@ mod tests {
|
||||||
Error::ParseError(string) => string,
|
Error::ParseError(string) => string,
|
||||||
_ => panic!(),
|
_ => panic!(),
|
||||||
};
|
};
|
||||||
assert_eq!(message, "Unknown element in roster item element.");
|
assert_eq!(message, "Unknown child in item element.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue