mam: Simplify parsing.

This commit is contained in:
Emmanuel Gil Peyrot 2017-10-31 21:10:04 +00:00
commit df069ac6c6

View file

@ -56,9 +56,8 @@ impl TryFrom<Element> for Query {
type Err = Error; type Err = Error;
fn try_from(elem: Element) -> Result<Query, Error> { fn try_from(elem: Element) -> Result<Query, Error> {
if !elem.is("query", ns::MAM) { check_self!(elem, "query", ns::MAM);
return Err(Error::ParseError("This is not a query element.")); check_no_unknown_attributes!(elem, "query", ["queryid", "node"]);
}
let mut form = None; let mut form = None;
let mut set = None; let mut set = None;
for child in elem.children() { for child in elem.children() {
@ -80,9 +79,8 @@ impl TryFrom<Element> for Result_ {
type Err = Error; type Err = Error;
fn try_from(elem: Element) -> Result<Result_, Error> { fn try_from(elem: Element) -> Result<Result_, Error> {
if !elem.is("result", ns::MAM) { check_self!(elem, "result", ns::MAM);
return Err(Error::ParseError("This is not a result element.")); check_no_unknown_attributes!(elem, "result", ["queryid", "id"]);
}
let mut forwarded = None; let mut forwarded = None;
for child in elem.children() { for child in elem.children() {
if child.is("forwarded", ns::FORWARD) { if child.is("forwarded", ns::FORWARD) {
@ -106,9 +104,8 @@ impl TryFrom<Element> for Fin {
type Err = Error; type Err = Error;
fn try_from(elem: Element) -> Result<Fin, Error> { fn try_from(elem: Element) -> Result<Fin, Error> {
if !elem.is("fin", ns::MAM) { check_self!(elem, "fin", ns::MAM);
return Err(Error::ParseError("This is not a fin element.")); check_no_unknown_attributes!(elem, "fin", ["complete"]);
}
let mut set = None; let mut set = None;
for child in elem.children() { for child in elem.children() {
if child.is("set", ns::RSM) { if child.is("set", ns::RSM) {
@ -132,9 +129,8 @@ impl TryFrom<Element> for Prefs {
type Err = Error; type Err = Error;
fn try_from(elem: Element) -> Result<Prefs, Error> { fn try_from(elem: Element) -> Result<Prefs, Error> {
if !elem.is("prefs", ns::MAM) { check_self!(elem, "prefs", ns::MAM);
return Err(Error::ParseError("This is not a prefs element.")); check_no_unknown_attributes!(elem, "prefs", ["default"]);
}
let mut always = vec!(); let mut always = vec!();
let mut never = vec!(); let mut never = vec!();
for child in elem.children() { for child in elem.children() {
@ -167,66 +163,57 @@ impl From<Query> for Element {
.ns(ns::MAM) .ns(ns::MAM)
.attr("queryid", query.queryid) .attr("queryid", query.queryid)
.attr("node", query.node) .attr("node", query.node)
//.append(query.form.map(Element::from)) //.append(query.form)
.append(query.set.map(Element::from)) .append(query.set)
.build() .build()
} }
} }
impl From<Result_> for Element { impl From<Result_> for Element {
fn from(result: Result_) -> Element { fn from(result: Result_) -> Element {
let mut elem = Element::builder("result") Element::builder("result")
.ns(ns::MAM) .ns(ns::MAM)
.attr("queryid", result.queryid) .attr("queryid", result.queryid)
.attr("id", result.id) .attr("id", result.id)
.build(); .append(result.forwarded)
elem.append_child(result.forwarded.into()); .build()
elem
} }
} }
impl From<Fin> for Element { impl From<Fin> for Element {
fn from(fin: Fin) -> Element { fn from(fin: Fin) -> Element {
let mut elem = Element::builder("fin") Element::builder("fin")
.ns(ns::MAM) .ns(ns::MAM)
.attr("complete", if fin.complete { Some("true") } else { None }) .attr("complete", if fin.complete { Some("true") } else { None })
.build(); .append(fin.set)
elem.append_child(fin.set.into()); .build()
elem }
}
fn serialise_jid_list(name: &str, jids: Vec<Jid>) -> Option<Element> {
if jids.is_empty() {
None
} else {
Some(Element::builder(name)
.ns(ns::MAM)
.append(jids.into_iter()
.map(|jid| Element::builder("jid")
.ns(ns::MAM)
.append(String::from(jid))
.build())
.collect::<Vec<_>>())
.build())
} }
} }
impl From<Prefs> for Element { impl From<Prefs> for Element {
fn from(prefs: Prefs) -> Element { fn from(prefs: Prefs) -> Element {
let mut elem = Element::builder("prefs") Element::builder("prefs")
.ns(ns::MAM) .ns(ns::MAM)
.attr("default", prefs.default_) .attr("default", prefs.default_)
.build(); .append(serialise_jid_list("always", prefs.always))
if !prefs.always.is_empty() { .append(serialise_jid_list("never", prefs.never))
let mut always = Element::builder("always") .build()
.ns(ns::RSM)
.build();
for jid in prefs.always {
always.append_child(Element::builder("jid")
.ns(ns::RSM)
.append(String::from(jid))
.build());
}
elem.append_child(always);
}
if !prefs.never.is_empty() {
let mut never = Element::builder("never")
.ns(ns::RSM)
.build();
for jid in prefs.never {
never.append_child(Element::builder("jid")
.ns(ns::RSM)
.append(String::from(jid))
.build());
}
elem.append_child(never);
}
elem
} }
} }
@ -320,7 +307,9 @@ mod tests {
#[test] #[test]
fn test_prefs_get() { fn test_prefs_get() {
let elem: Element = "<prefs xmlns='urn:xmpp:mam:2' default='always'/>".parse().unwrap(); let elem: Element = "<prefs xmlns='urn:xmpp:mam:2' default='always'/>".parse().unwrap();
Prefs::try_from(elem).unwrap(); let prefs = Prefs::try_from(elem).unwrap();
assert_eq!(prefs.always, vec!());
assert_eq!(prefs.never, vec!());
let elem: Element = r#" let elem: Element = r#"
<prefs xmlns='urn:xmpp:mam:2' default='roster'> <prefs xmlns='urn:xmpp:mam:2' default='roster'>
@ -328,7 +317,9 @@ mod tests {
<never/> <never/>
</prefs> </prefs>
"#.parse().unwrap(); "#.parse().unwrap();
Prefs::try_from(elem).unwrap(); let prefs = Prefs::try_from(elem).unwrap();
assert_eq!(prefs.always, vec!());
assert_eq!(prefs.never, vec!());
} }
#[test] #[test]
@ -343,7 +334,16 @@ mod tests {
</never> </never>
</prefs> </prefs>
"#.parse().unwrap(); "#.parse().unwrap();
Prefs::try_from(elem).unwrap(); let prefs = Prefs::try_from(elem).unwrap();
assert_eq!(prefs.always, vec!(Jid::from_str("romeo@montague.lit").unwrap()));
assert_eq!(prefs.never, vec!(Jid::from_str("montague@montague.lit").unwrap()));
let elem2 = Element::from(prefs.clone());
println!("{:?}", elem2);
let prefs2 = Prefs::try_from(elem2).unwrap();
assert_eq!(prefs.default_, prefs2.default_);
assert_eq!(prefs.always, prefs2.always);
assert_eq!(prefs.never, prefs2.never);
} }
#[test] #[test]