rsm: Switch to Into/TryFrom.

Emmanuel Gil Peyrot created

Change summary

src/mam.rs |  11 +-
src/rsm.rs | 212 ++++++++++++++++++++++++++++---------------------------
2 files changed, 115 insertions(+), 108 deletions(-)

Detailed changes

src/mam.rs 🔗

@@ -4,6 +4,8 @@
 // License, v. 2.0. If a copy of the MPL was not distributed with this
 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+use std::convert::TryFrom;
+
 use minidom::Element;
 use jid::Jid;
 
@@ -11,7 +13,6 @@ use error::Error;
 
 use data_forms;
 use data_forms::DataForm;
-use rsm;
 use rsm::Set;
 use forwarding;
 use forwarding::Forwarded;
@@ -63,7 +64,7 @@ pub fn parse_query(root: &Element) -> Result<Query, Error> {
         if child.is("x", ns::DATA_FORMS) {
             form = Some(data_forms::parse_data_form(child)?);
         } else if child.is("set", ns::RSM) {
-            set = Some(rsm::parse_rsm(child)?);
+            set = Some(Set::try_from(child)?);
         } else {
             return Err(Error::ParseError("Unknown child in query element."));
         }
@@ -117,7 +118,7 @@ pub fn parse_fin(root: &Element) -> Result<Fin, Error> {
     let mut set = None;
     for child in root.children() {
         if child.is("set", ns::RSM) {
-            set = Some(rsm::parse_rsm(child)?);
+            set = Some(Set::try_from(child)?);
         } else {
             return Err(Error::ParseError("Unknown child in fin element."));
         }
@@ -179,7 +180,7 @@ pub fn serialise_query(query: &Query) -> Element {
     //    elem.append_child(data_forms::serialise(&form));
     //}
     if let Some(ref set) = query.set {
-        elem.append_child(rsm::serialise(&set));
+        elem.append_child(set.into());
     }
     elem
 }
@@ -202,7 +203,7 @@ pub fn serialise_fin(fin: &Fin) -> Element {
                                 false => None,
                             })
                            .build();
-    elem.append_child(rsm::serialise(&fin.set));
+    elem.append_child((&fin.set).into());
     elem
 }
 

src/rsm.rs 🔗

@@ -4,6 +4,8 @@
 // License, v. 2.0. If a copy of the MPL was not distributed with this
 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
+use std::convert::TryFrom;
+
 use minidom::Element;
 
 use error::Error;
@@ -27,119 +29,123 @@ pub struct Set {
     pub max: Option<usize>,
 }
 
-pub fn parse_rsm(root: &Element) -> Result<Set, Error> {
-    if !root.is("set", ns::RSM) {
-        return Err(Error::ParseError("This is not a RSM element."));
-    }
-    let mut after = None;
-    let mut before = None;
-    let mut count = None;
-    let mut first = None;
-    let mut index = None;
-    let mut last = None;
-    let mut max = None;
-    for child in root.children() {
-        if child.is("after", ns::RSM) {
-            if after.is_some() {
-                return Err(Error::ParseError("Set can’t have more than one after."));
-            }
-            after = Some(child.text());
-        } else if child.is("before", ns::RSM) {
-            if before.is_some() {
-                return Err(Error::ParseError("Set can’t have more than one before."));
-            }
-            before = Some(child.text());
-        } else if child.is("count", ns::RSM) {
-            if count.is_some() {
-                return Err(Error::ParseError("Set can’t have more than one count."));
-            }
-            count = Some(child.text().parse()?);
-        } else if child.is("first", ns::RSM) {
-            if first.is_some() {
-                return Err(Error::ParseError("Set can’t have more than one first."));
-            }
-            first = Some(First {
-                index: match child.attr("index") {
-                    Some(index) => Some(index.parse()?),
-                    None => None,
-                },
-                base: child.text(),
-            });
-        } else if child.is("index", ns::RSM) {
-            if index.is_some() {
-                return Err(Error::ParseError("Set can’t have more than one index."));
-            }
-            index = Some(child.text().parse()?);
-        } else if child.is("last", ns::RSM) {
-            if last.is_some() {
-                return Err(Error::ParseError("Set can’t have more than one last."));
-            }
-            last = Some(child.text());
-        } else if child.is("max", ns::RSM) {
-            if max.is_some() {
-                return Err(Error::ParseError("Set can’t have more than one max."));
+impl<'a> TryFrom<&'a Element> for Set {
+    type Error = Error;
+
+    fn try_from(elem: &'a Element) -> Result<Set, Error> {
+        if !elem.is("set", ns::RSM) {
+            return Err(Error::ParseError("This is not a RSM element."));
+        }
+        let mut after = None;
+        let mut before = None;
+        let mut count = None;
+        let mut first = None;
+        let mut index = None;
+        let mut last = None;
+        let mut max = None;
+        for child in elem.children() {
+            if child.is("after", ns::RSM) {
+                if after.is_some() {
+                    return Err(Error::ParseError("Set can’t have more than one after."));
+                }
+                after = Some(child.text());
+            } else if child.is("before", ns::RSM) {
+                if before.is_some() {
+                    return Err(Error::ParseError("Set can’t have more than one before."));
+                }
+                before = Some(child.text());
+            } else if child.is("count", ns::RSM) {
+                if count.is_some() {
+                    return Err(Error::ParseError("Set can’t have more than one count."));
+                }
+                count = Some(child.text().parse()?);
+            } else if child.is("first", ns::RSM) {
+                if first.is_some() {
+                    return Err(Error::ParseError("Set can’t have more than one first."));
+                }
+                first = Some(First {
+                    index: match child.attr("index") {
+                        Some(index) => Some(index.parse()?),
+                        None => None,
+                    },
+                    base: child.text(),
+                });
+            } else if child.is("index", ns::RSM) {
+                if index.is_some() {
+                    return Err(Error::ParseError("Set can’t have more than one index."));
+                }
+                index = Some(child.text().parse()?);
+            } else if child.is("last", ns::RSM) {
+                if last.is_some() {
+                    return Err(Error::ParseError("Set can’t have more than one last."));
+                }
+                last = Some(child.text());
+            } else if child.is("max", ns::RSM) {
+                if max.is_some() {
+                    return Err(Error::ParseError("Set can’t have more than one max."));
+                }
+                max = Some(child.text().parse()?);
+            } else {
+                return Err(Error::ParseError("Unknown child in set element."));
             }
-            max = Some(child.text().parse()?);
-        } else {
-            return Err(Error::ParseError("Unknown child in set element."));
         }
+        Ok(Set {
+            after: after,
+            before: before,
+            count: count,
+            first: first,
+            index: index,
+            last: last,
+            max: max,
+        })
     }
-    Ok(Set {
-        after: after,
-        before: before,
-        count: count,
-        first: first,
-        index: index,
-        last: last,
-        max: max,
-    })
 }
 
-pub fn serialise(rsm: &Set) -> Element {
-    let mut elem = Element::builder("set")
-                           .ns(ns::RSM)
-                           .build();
-    if rsm.after.is_some() {
-        elem.append_child(Element::builder("after").ns(ns::RSM).append(rsm.after.clone()).build());
-    }
-    if rsm.before.is_some() {
-        elem.append_child(Element::builder("before").ns(ns::RSM).append(rsm.before.clone()).build());
-    }
-    if rsm.count.is_some() {
-        elem.append_child(Element::builder("count").ns(ns::RSM).append(format!("{}", rsm.count.unwrap())).build());
-    }
-    if rsm.first.is_some() {
-        let first = rsm.first.clone().unwrap();
-        elem.append_child(Element::builder("first")
-                                  .ns(ns::RSM)
-                                  .attr("index", match first.index {
-                                       Some(index) => Some(format!("{}", index)),
-                                       None => None,
-                                   })
-                                  .append(first.base.clone()).build());
-    }
-    if rsm.index.is_some() {
-        elem.append_child(Element::builder("index").ns(ns::RSM).append(format!("{}", rsm.index.unwrap())).build());
-    }
-    if rsm.last.is_some() {
-        elem.append_child(Element::builder("last").ns(ns::RSM).append(rsm.last.clone()).build());
-    }
-    if rsm.max.is_some() {
-        elem.append_child(Element::builder("max").ns(ns::RSM).append(format!("{}", rsm.max.unwrap())).build());
+impl<'a> Into<Element> for &'a Set {
+    fn into(self) -> Element {
+        let mut elem = Element::builder("set")
+                               .ns(ns::RSM)
+                               .build();
+        if self.after.is_some() {
+            elem.append_child(Element::builder("after").ns(ns::RSM).append(self.after.clone()).build());
+        }
+        if self.before.is_some() {
+            elem.append_child(Element::builder("before").ns(ns::RSM).append(self.before.clone()).build());
+        }
+        if self.count.is_some() {
+            elem.append_child(Element::builder("count").ns(ns::RSM).append(format!("{}", self.count.unwrap())).build());
+        }
+        if self.first.is_some() {
+            let first = self.first.clone().unwrap();
+            elem.append_child(Element::builder("first")
+                                      .ns(ns::RSM)
+                                      .attr("index", match first.index {
+                                           Some(index) => Some(format!("{}", index)),
+                                           None => None,
+                                       })
+                                      .append(first.base.clone()).build());
+        }
+        if self.index.is_some() {
+            elem.append_child(Element::builder("index").ns(ns::RSM).append(format!("{}", self.index.unwrap())).build());
+        }
+        if self.last.is_some() {
+            elem.append_child(Element::builder("last").ns(ns::RSM).append(self.last.clone()).build());
+        }
+        if self.max.is_some() {
+            elem.append_child(Element::builder("max").ns(ns::RSM).append(format!("{}", self.max.unwrap())).build());
+        }
+        elem
     }
-    elem
 }
 
 #[cfg(test)]
 mod tests {
-    use minidom::Element;
-    use error::Error;
-    use rsm;
+    use super::*;
 
     #[test]
     fn test_simple() {
         let elem: Element = "<set xmlns='http://jabber.org/protocol/rsm'/>".parse().unwrap();
-        let set = rsm::parse_rsm(&elem).unwrap();
+        let set = Set::try_from(&elem).unwrap();
         assert_eq!(set.after, None);
         assert_eq!(set.before, None);
         assert_eq!(set.count, None);
@@ -155,7 +161,7 @@ mod tests {
     #[test]
     fn test_unknown() {
         let elem: Element = "<replace xmlns='urn:xmpp:message-correct:0'/>".parse().unwrap();
-        let error = rsm::parse_rsm(&elem).unwrap_err();
+        let error = Set::try_from(&elem).unwrap_err();
         let message = match error {
             Error::ParseError(string) => string,
             _ => panic!(),
@@ -166,7 +172,7 @@ mod tests {
     #[test]
     fn test_invalid_child() {
         let elem: Element = "<set xmlns='http://jabber.org/protocol/rsm'><coucou/></set>".parse().unwrap();
-        let error = rsm::parse_rsm(&elem).unwrap_err();
+        let error = Set::try_from(&elem).unwrap_err();
         let message = match error {
             Error::ParseError(string) => string,
             _ => panic!(),
@@ -177,7 +183,7 @@ mod tests {
     #[test]
     fn test_serialise() {
         let elem: Element = "<set xmlns='http://jabber.org/protocol/rsm'/>".parse().unwrap();
-        let rsm = rsm::Set {
+        let rsm = Set {
             after: None,
             before: None,
             count: None,
@@ -186,7 +192,7 @@ mod tests {
             last: None,
             max: None,
         };
-        let elem2 = rsm::serialise(&rsm);
+        let elem2 = (&rsm).into();
         assert_eq!(elem, elem2);
     }
 }