roster: Make Group a proper struct.
This commit is contained in:
parent
5388696b95
commit
6ec1e46953
2 changed files with 33 additions and 7 deletions
22
src/lib.rs
22
src/lib.rs
|
@ -144,6 +144,28 @@ macro_rules! generate_id {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! generate_elem_id {
|
||||||
|
($elem:ident, $name:tt, $ns:expr) => (
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub struct $elem(pub String);
|
||||||
|
impl FromStr for $elem {
|
||||||
|
type Err = Error;
|
||||||
|
fn from_str(s: &str) -> Result<$elem, Error> {
|
||||||
|
// TODO: add a way to parse that differently when needed.
|
||||||
|
Ok($elem(String::from(s)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl From<$elem> for Element {
|
||||||
|
fn from(elem: $elem) -> Element {
|
||||||
|
Element::builder($name)
|
||||||
|
.ns($ns)
|
||||||
|
.append(elem.0)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// Error type returned by every parser on failure.
|
/// Error type returned by every parser on failure.
|
||||||
pub mod error;
|
pub mod error;
|
||||||
/// XML namespace definitions used through XMPP.
|
/// XML namespace definitions used through XMPP.
|
||||||
|
|
|
@ -13,7 +13,7 @@ use jid::Jid;
|
||||||
use error::Error;
|
use error::Error;
|
||||||
use ns;
|
use ns;
|
||||||
|
|
||||||
type Group = String;
|
generate_elem_id!(Group, "group", ns::ROSTER);
|
||||||
|
|
||||||
generate_attribute!(Subscription, "subscription", {
|
generate_attribute!(Subscription, "subscription", {
|
||||||
None => "none",
|
None => "none",
|
||||||
|
@ -52,7 +52,11 @@ impl TryFrom<Element> for Item {
|
||||||
for _ in child.children() {
|
for _ in child.children() {
|
||||||
return Err(Error::ParseError("Roster item group can’t have children."));
|
return Err(Error::ParseError("Roster item group can’t have children."));
|
||||||
}
|
}
|
||||||
item.groups.push(child.text());
|
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)
|
Ok(item)
|
||||||
}
|
}
|
||||||
|
@ -65,7 +69,7 @@ impl From<Item> for Element {
|
||||||
.attr("jid", String::from(item.jid))
|
.attr("jid", String::from(item.jid))
|
||||||
.attr("name", item.name)
|
.attr("name", item.name)
|
||||||
.attr("subscription", item.subscription)
|
.attr("subscription", item.subscription)
|
||||||
.append(item.groups.into_iter().map(|group| Element::builder("group").ns(ns::ROSTER).append(group)).collect::<Vec<_>>())
|
.append(item.groups)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -163,7 +167,7 @@ mod tests {
|
||||||
assert_eq!(roster.items[0].jid, Jid::from_str("romeo@example.net").unwrap());
|
assert_eq!(roster.items[0].jid, Jid::from_str("romeo@example.net").unwrap());
|
||||||
assert_eq!(roster.items[0].name, Some(String::from("Romeo")));
|
assert_eq!(roster.items[0].name, Some(String::from("Romeo")));
|
||||||
assert_eq!(roster.items[0].subscription, Some(Subscription::Both));
|
assert_eq!(roster.items[0].subscription, Some(Subscription::Both));
|
||||||
assert_eq!(roster.items[0].groups, vec!(String::from("Friends")));
|
assert_eq!(roster.items[0].groups, vec!(Group::from_str("Friends").unwrap()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -183,8 +187,8 @@ mod tests {
|
||||||
assert_eq!(roster.items[0].jid, Jid::from_str("test@example.org").unwrap());
|
assert_eq!(roster.items[0].jid, Jid::from_str("test@example.org").unwrap());
|
||||||
assert_eq!(roster.items[0].name, None);
|
assert_eq!(roster.items[0].name, None);
|
||||||
assert_eq!(roster.items[0].groups.len(), 2);
|
assert_eq!(roster.items[0].groups.len(), 2);
|
||||||
assert_eq!(roster.items[0].groups[0], String::from("A"));
|
assert_eq!(roster.items[0].groups[0], Group::from_str("A").unwrap());
|
||||||
assert_eq!(roster.items[0].groups[1], String::from("B"));
|
assert_eq!(roster.items[0].groups[1], Group::from_str("B").unwrap());
|
||||||
let elem2 = roster.into();
|
let elem2 = roster.into();
|
||||||
assert_eq!(elem1, elem2);
|
assert_eq!(elem1, elem2);
|
||||||
}
|
}
|
||||||
|
@ -210,7 +214,7 @@ mod tests {
|
||||||
assert_eq!(roster.items[0].jid, Jid::from_str("nurse@example.com").unwrap());
|
assert_eq!(roster.items[0].jid, Jid::from_str("nurse@example.com").unwrap());
|
||||||
assert_eq!(roster.items[0].name, Some(String::from("Nurse")));
|
assert_eq!(roster.items[0].name, Some(String::from("Nurse")));
|
||||||
assert_eq!(roster.items[0].groups.len(), 1);
|
assert_eq!(roster.items[0].groups.len(), 1);
|
||||||
assert_eq!(roster.items[0].groups[0], String::from("Servants"));
|
assert_eq!(roster.items[0].groups[0], Group::from_str("Servants").unwrap());
|
||||||
|
|
||||||
let elem: Element = r#"
|
let elem: Element = r#"
|
||||||
<query xmlns='jabber:iq:roster'>
|
<query xmlns='jabber:iq:roster'>
|
||||||
|
|
Loading…
Reference in a new issue