From 7ebabf7e9103b2938caf5c7a1819dad7a095bf7c Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Sat, 6 May 2017 20:10:35 +0100 Subject: [PATCH] stanza_id: Switch to Into/TryFrom. --- src/stanza_id.rs | 102 ++++++++++++++++++++++++----------------------- 1 file changed, 53 insertions(+), 49 deletions(-) diff --git a/src/stanza_id.rs b/src/stanza_id.rs index 5d34c3d..d478b1a 100644 --- a/src/stanza_id.rs +++ b/src/stanza_id.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; @@ -22,61 +24,63 @@ pub enum StanzaId { }, } -pub fn parse_stanza_id(root: &Element) -> Result { - let is_stanza_id = root.is("stanza-id", ns::SID); - if !is_stanza_id && !root.is("origin-id", ns::SID) { - return Err(Error::ParseError("This is not a stanza-id or origin-id element.")); - } - for _ in root.children() { - return Err(Error::ParseError("Unknown child in stanza-id or origin-id element.")); - } - let id = match root.attr("id") { - Some(id) => id.to_owned(), - None => return Err(Error::ParseError("No 'id' attribute present in stanza-id or origin-id.")), - }; - Ok(if is_stanza_id { - let by = match root.attr("by") { - Some(by) => by.parse().unwrap(), - None => return Err(Error::ParseError("No 'by' attribute present in stanza-id.")), +impl<'a> TryFrom<&'a Element> for StanzaId { + type Error = Error; + + fn try_from(elem: &'a Element) -> Result { + let is_stanza_id = elem.is("stanza-id", ns::SID); + if !is_stanza_id && !elem.is("origin-id", ns::SID) { + return Err(Error::ParseError("This is not a stanza-id or origin-id element.")); + } + for _ in elem.children() { + return Err(Error::ParseError("Unknown child in stanza-id or origin-id element.")); + } + let id = match elem.attr("id") { + Some(id) => id.to_owned(), + None => return Err(Error::ParseError("No 'id' attribute present in stanza-id or origin-id.")), }; - StanzaId::StanzaId { id, by } - } else { - StanzaId::OriginId { id } - }) + Ok(if is_stanza_id { + let by = match elem.attr("by") { + Some(by) => by.parse().unwrap(), + None => return Err(Error::ParseError("No 'by' attribute present in stanza-id.")), + }; + StanzaId::StanzaId { id, by } + } else { + StanzaId::OriginId { id } + }) + } } -pub fn serialise(stanza_id: &StanzaId) -> Element { - match *stanza_id { - StanzaId::StanzaId { ref id, ref by } => { - Element::builder("stanza-id") - .ns(ns::SID) - .attr("id", id.clone()) - .attr("by", String::from(by.clone())) - .build() - }, - StanzaId::OriginId { ref id } => { - Element::builder("origin-id") - .ns(ns::SID) - .attr("id", id.clone()) - .build() - }, +impl<'a> Into for &'a StanzaId { + fn into(self) -> Element { + match *self { + StanzaId::StanzaId { ref id, ref by } => { + Element::builder("stanza-id") + .ns(ns::SID) + .attr("id", id.clone()) + .attr("by", String::from(by.clone())) + .build() + }, + StanzaId::OriginId { ref id } => { + Element::builder("origin-id") + .ns(ns::SID) + .attr("id", id.clone()) + .build() + }, + } } } #[cfg(test)] mod tests { + use super::*; use std::str::FromStr; - use minidom::Element; - use jid::Jid; - use error::Error; - use stanza_id; - #[test] fn test_simple() { let elem: Element = "".parse().unwrap(); - let stanza_id = stanza_id::parse_stanza_id(&elem).unwrap(); - if let stanza_id::StanzaId::StanzaId { id, by } = stanza_id { + let stanza_id = StanzaId::try_from(&elem).unwrap(); + if let StanzaId::StanzaId { id, by } = stanza_id { assert_eq!(id, String::from("coucou")); assert_eq!(by, Jid::from_str("coucou@coucou").unwrap()); } else { @@ -84,8 +88,8 @@ mod tests { } let elem: Element = "".parse().unwrap(); - let stanza_id = stanza_id::parse_stanza_id(&elem).unwrap(); - if let stanza_id::StanzaId::OriginId { id } = stanza_id { + let stanza_id = StanzaId::try_from(&elem).unwrap(); + if let StanzaId::OriginId { id } = stanza_id { assert_eq!(id, String::from("coucou")); } else { panic!(); @@ -95,7 +99,7 @@ mod tests { #[test] fn test_invalid_child() { let elem: Element = "".parse().unwrap(); - let error = stanza_id::parse_stanza_id(&elem).unwrap_err(); + let error = StanzaId::try_from(&elem).unwrap_err(); let message = match error { Error::ParseError(string) => string, _ => panic!(), @@ -106,7 +110,7 @@ mod tests { #[test] fn test_invalid_id() { let elem: Element = "".parse().unwrap(); - let error = stanza_id::parse_stanza_id(&elem).unwrap_err(); + let error = StanzaId::try_from(&elem).unwrap_err(); let message = match error { Error::ParseError(string) => string, _ => panic!(), @@ -117,7 +121,7 @@ mod tests { #[test] fn test_invalid_by() { let elem: Element = "".parse().unwrap(); - let error = stanza_id::parse_stanza_id(&elem).unwrap_err(); + let error = StanzaId::try_from(&elem).unwrap_err(); let message = match error { Error::ParseError(string) => string, _ => panic!(), @@ -128,8 +132,8 @@ mod tests { #[test] fn test_serialise() { let elem: Element = "".parse().unwrap(); - let stanza_id = stanza_id::StanzaId::StanzaId { id: String::from("coucou"), by: Jid::from_str("coucou@coucou").unwrap() }; - let elem2 = stanza_id::serialise(&stanza_id); + let stanza_id = StanzaId::StanzaId { id: String::from("coucou"), by: Jid::from_str("coucou@coucou").unwrap() }; + let elem2 = (&stanza_id).into(); assert_eq!(elem, elem2); } }