jingle: Update to Into and TryFrom.

Emmanuel Gil Peyrot created

Change summary

src/iq.rs     |  10 
src/jingle.rs | 392 +++++++++++++++++++++++++++-------------------------
2 files changed, 208 insertions(+), 194 deletions(-)

Detailed changes

src/iq.rs 🔗

@@ -5,6 +5,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 minidom::IntoAttributeValue;
 
@@ -17,7 +19,7 @@ use ns;
 use stanza_error;
 use disco;
 use ibb;
-use jingle;
+use jingle::Jingle;
 use ping;
 
 /// Lists every known payload of a `<iq/>`.
@@ -25,7 +27,7 @@ use ping;
 pub enum IqPayload {
     Disco(disco::Disco),
     IBB(ibb::IBB),
-    Jingle(jingle::Jingle),
+    Jingle(Jingle),
     Ping(ping::Ping),
 }
 
@@ -97,7 +99,7 @@ pub fn parse_iq(root: &Element) -> Result<Iq, Error> {
                 Some(IqPayload::Disco(disco))
             } else if let Ok(ibb) = ibb::parse_ibb(elem) {
                 Some(IqPayload::IBB(ibb))
-            } else if let Ok(jingle) = jingle::parse_jingle(elem) {
+            } else if let Ok(jingle) = Jingle::try_from(elem) {
                 Some(IqPayload::Jingle(jingle))
             } else if let Ok(ping) = ping::parse_ping(elem) {
                 Some(IqPayload::Ping(ping))
@@ -152,7 +154,7 @@ pub fn serialise_payload(payload: &IqPayload) -> Element {
     match *payload {
         IqPayload::Disco(ref disco) => disco::serialise_disco(disco),
         IqPayload::IBB(ref ibb) => ibb::serialise(ibb),
-        IqPayload::Jingle(ref jingle) => jingle::serialise(jingle),
+        IqPayload::Jingle(ref jingle) => jingle.into(),
         IqPayload::Ping(_) => ping::serialise_ping(),
     }
 }

src/jingle.rs 🔗

@@ -4,10 +4,10 @@
 // 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 std::str::FromStr;
 
-use minidom::{Element, IntoElements};
-use minidom::convert::ElementEmitter;
+use minidom::Element;
 
 use error::Error;
 use ns;
@@ -204,9 +204,9 @@ impl FromStr for Reason {
     }
 }
 
-impl IntoElements for Reason {
-    fn into_elements(self, emitter: &mut ElementEmitter) {
-        let elem = Element::builder(match self {
+impl<'a> Into<Element> for &'a Reason {
+    fn into(self) -> Element {
+        Element::builder(match *self {
             Reason::AlternativeSession => "alternative-session",
             Reason::Busy => "busy",
             Reason::Cancel => "cancel",
@@ -224,8 +224,7 @@ impl IntoElements for Reason {
             Reason::Timeout => "timeout",
             Reason::UnsupportedApplications => "unsupported-applications",
             Reason::UnsupportedTransports => "unsupported-transports",
-        }).build();
-        emitter.append_child(elem);
+        }).build()
     }
 }
 
@@ -246,195 +245,208 @@ pub struct Jingle {
     pub other: Vec<Element>,
 }
 
-pub fn parse_jingle(root: &Element) -> Result<Jingle, Error> {
-    if !root.is("jingle", ns::JINGLE) {
-        return Err(Error::ParseError("This is not a Jingle element."));
-    }
+impl<'a> TryFrom<&'a Element> for Jingle {
+    type Error = Error;
 
-    let mut contents: Vec<Content> = vec!();
-
-    let action = root.attr("action")
-                     .ok_or(Error::ParseError("Jingle must have an 'action' attribute."))?
-                     .parse()?;
-    let initiator = root.attr("initiator")
-                        .and_then(|initiator| initiator.parse().ok());
-    let responder = root.attr("responder")
-                        .and_then(|responder| responder.parse().ok());
-    let sid = root.attr("sid")
-                  .ok_or(Error::ParseError("Jingle must have a 'sid' attribute."))?;
-    let mut reason_element = None;
-    let mut other = vec!();
-
-    for child in root.children() {
-        if child.is("content", ns::JINGLE) {
-            let creator = child.attr("creator")
-                               .ok_or(Error::ParseError("Content must have a 'creator' attribute."))?
-                               .parse()?;
-            let disposition = child.attr("disposition")
-                                   .unwrap_or("session");
-            let name = child.attr("name")
-                            .ok_or(Error::ParseError("Content must have a 'name' attribute."))?;
-            let senders = child.attr("senders")
-                               .unwrap_or("both")
-                               .parse()?;
-            let mut description = None;
-            let mut transport = None;
-            let mut security = None;
-            for stuff in child.children() {
-                if stuff.name() == "description" {
-                    if description.is_some() {
-                        return Err(Error::ParseError("Content must not have more than one description."));
-                    }
-                    let namespace = stuff.ns()
-                                         .and_then(|ns| ns.parse().ok())
-                                         // TODO: is this even reachable?
-                                         .ok_or(Error::ParseError("Invalid namespace on description element."))?;
-                    description = Some((
-                        namespace,
-                        stuff.clone(),
-                    ));
-                } else if stuff.name() == "transport" {
-                    if transport.is_some() {
-                        return Err(Error::ParseError("Content must not have more than one transport."));
-                    }
-                    let namespace = stuff.ns()
-                                         .and_then(|ns| ns.parse().ok())
-                                         // TODO: is this even reachable?
-                                         .ok_or(Error::ParseError("Invalid namespace on transport element."))?;
-                    transport = Some((
-                        namespace,
-                        stuff.clone(),
-                    ));
-                } else if stuff.name() == "security" {
-                    if security.is_some() {
-                        return Err(Error::ParseError("Content must not have more than one security."));
+    fn try_from(root: &'a Element) -> Result<Jingle, Error> {
+        if !root.is("jingle", ns::JINGLE) {
+            return Err(Error::ParseError("This is not a Jingle element."));
+        }
+
+        let mut contents: Vec<Content> = vec!();
+
+        let action = root.attr("action")
+                         .ok_or(Error::ParseError("Jingle must have an 'action' attribute."))?
+                         .parse()?;
+        let initiator = root.attr("initiator")
+                            .and_then(|initiator| initiator.parse().ok());
+        let responder = root.attr("responder")
+                            .and_then(|responder| responder.parse().ok());
+        let sid = root.attr("sid")
+                      .ok_or(Error::ParseError("Jingle must have a 'sid' attribute."))?;
+        let mut reason_element = None;
+        let mut other = vec!();
+
+        for child in root.children() {
+            if child.is("content", ns::JINGLE) {
+                let creator = child.attr("creator")
+                                   .ok_or(Error::ParseError("Content must have a 'creator' attribute."))?
+                                   .parse()?;
+                let disposition = child.attr("disposition")
+                                       .unwrap_or("session");
+                let name = child.attr("name")
+                                .ok_or(Error::ParseError("Content must have a 'name' attribute."))?;
+                let senders = child.attr("senders")
+                                   .unwrap_or("both")
+                                   .parse()?;
+                let mut description = None;
+                let mut transport = None;
+                let mut security = None;
+                for stuff in child.children() {
+                    if stuff.name() == "description" {
+                        if description.is_some() {
+                            return Err(Error::ParseError("Content must not have more than one description."));
+                        }
+                        let namespace = stuff.ns()
+                                             .and_then(|ns| ns.parse().ok())
+                                             // TODO: is this even reachable?
+                                             .ok_or(Error::ParseError("Invalid namespace on description element."))?;
+                        description = Some((
+                            namespace,
+                            stuff.clone(),
+                        ));
+                    } else if stuff.name() == "transport" {
+                        if transport.is_some() {
+                            return Err(Error::ParseError("Content must not have more than one transport."));
+                        }
+                        let namespace = stuff.ns()
+                                             .and_then(|ns| ns.parse().ok())
+                                             // TODO: is this even reachable?
+                                             .ok_or(Error::ParseError("Invalid namespace on transport element."))?;
+                        transport = Some((
+                            namespace,
+                            stuff.clone(),
+                        ));
+                    } else if stuff.name() == "security" {
+                        if security.is_some() {
+                            return Err(Error::ParseError("Content must not have more than one security."));
+                        }
+                        let namespace = stuff.ns()
+                                             .and_then(|ns| ns.parse().ok())
+                                             // TODO: is this even reachable?
+                                             .ok_or(Error::ParseError("Invalid namespace on security element."))?;
+                        security = Some((
+                            namespace,
+                            stuff.clone(),
+                        ));
                     }
-                    let namespace = stuff.ns()
-                                         .and_then(|ns| ns.parse().ok())
-                                         // TODO: is this even reachable?
-                                         .ok_or(Error::ParseError("Invalid namespace on security element."))?;
-                    security = Some((
-                        namespace,
-                        stuff.clone(),
-                    ));
                 }
-            }
-            if description.is_none() {
-                return Err(Error::ParseError("Content must have one description."));
-            }
-            if transport.is_none() {
-                return Err(Error::ParseError("Content must have one transport."));
-            }
-            let description = description.unwrap().to_owned();
-            let transport = transport.unwrap().to_owned();
-            contents.push(Content {
-                creator: creator,
-                disposition: disposition.to_owned(),
-                name: name.to_owned(),
-                senders: senders,
-                description: description,
-                transport: transport,
-                security: security,
-            });
-        } else if child.is("reason", ns::JINGLE) {
-            if reason_element.is_some() {
-                return Err(Error::ParseError("Jingle must not have more than one reason."));
-            }
-            let mut reason = None;
-            let mut text = None;
-            for stuff in child.children() {
-                if stuff.ns() != Some(ns::JINGLE) {
-                    return Err(Error::ParseError("Reason contains a foreign element."));
+                if description.is_none() {
+                    return Err(Error::ParseError("Content must have one description."));
+                }
+                if transport.is_none() {
+                    return Err(Error::ParseError("Content must have one transport."));
+                }
+                let description = description.unwrap().to_owned();
+                let transport = transport.unwrap().to_owned();
+                contents.push(Content {
+                    creator: creator,
+                    disposition: disposition.to_owned(),
+                    name: name.to_owned(),
+                    senders: senders,
+                    description: description,
+                    transport: transport,
+                    security: security,
+                });
+            } else if child.is("reason", ns::JINGLE) {
+                if reason_element.is_some() {
+                    return Err(Error::ParseError("Jingle must not have more than one reason."));
                 }
-                let name = stuff.name();
-                if name == "text" {
-                    if text.is_some() {
-                        return Err(Error::ParseError("Reason must not have more than one text."));
+                let mut reason = None;
+                let mut text = None;
+                for stuff in child.children() {
+                    if stuff.ns() != Some(ns::JINGLE) {
+                        return Err(Error::ParseError("Reason contains a foreign element."));
+                    }
+                    let name = stuff.name();
+                    if name == "text" {
+                        if text.is_some() {
+                            return Err(Error::ParseError("Reason must not have more than one text."));
+                        }
+                        text = Some(stuff.text());
+                    } else {
+                        reason = Some(name.parse()?);
                     }
-                    text = Some(stuff.text());
-                } else {
-                    reason = Some(name.parse()?);
                 }
+                if reason.is_none() {
+                    return Err(Error::ParseError("Reason doesn’t contain a valid reason."));
+                }
+                reason_element = Some(ReasonElement {
+                    reason: reason.unwrap(),
+                    text: text,
+                });
+            } else {
+                other.push(child.clone());
             }
-            if reason.is_none() {
-                return Err(Error::ParseError("Reason doesn’t contain a valid reason."));
-            }
-            reason_element = Some(ReasonElement {
-                reason: reason.unwrap(),
-                text: text,
-            });
-        } else {
-            other.push(child.clone());
         }
-    }
 
-    Ok(Jingle {
-        action: action,
-        initiator: initiator,
-        responder: responder,
-        sid: sid.to_owned(),
-        contents: contents,
-        reason: reason_element,
-        other: other,
-    })
+        Ok(Jingle {
+            action: action,
+            initiator: initiator,
+            responder: responder,
+            sid: sid.to_owned(),
+            contents: contents,
+            reason: reason_element,
+            other: other,
+        })
+    }
 }
 
-pub fn serialise_content(content: &Content) -> Element {
-    let mut root = Element::builder("content")
-                           .ns(ns::JINGLE)
-                           .attr("creator", String::from(content.creator.clone()))
-                           .attr("disposition", content.disposition.clone())
-                           .attr("name", content.name.clone())
-                           .attr("senders", String::from(content.senders.clone()))
-                           .build();
-    root.append_child(content.description.1.clone());
-    root.append_child(content.transport.1.clone());
-    if let Some(security) = content.security.clone() {
-        root.append_child(security.1.clone());
+impl<'a> Into<Element> for &'a Content {
+    fn into(self) -> Element {
+        let mut root = Element::builder("content")
+                               .ns(ns::JINGLE)
+                               .attr("creator", String::from(self.creator.clone()))
+                               .attr("disposition", self.disposition.clone())
+                               .attr("name", self.name.clone())
+                               .attr("senders", String::from(self.senders.clone()))
+                               .build();
+        root.append_child(self.description.1.clone());
+        root.append_child(self.transport.1.clone());
+        if let Some(security) = self.security.clone() {
+            root.append_child(security.1.clone());
+        }
+        root
     }
-    root
 }
 
-pub fn serialise(jingle: &Jingle) -> Element {
-    let mut root = Element::builder("jingle")
-                           .ns(ns::JINGLE)
-                           .attr("action", String::from(jingle.action.clone()))
-                           .attr("initiator", jingle.initiator.clone())
-                           .attr("responder", jingle.responder.clone())
-                           .attr("sid", jingle.sid.clone())
-                           .build();
-    for content in jingle.contents.clone() {
-        let content_elem = serialise_content(&content);
-        root.append_child(content_elem);
+impl<'a> Into<Element> for &'a Jingle {
+    fn into(self) -> Element {
+        let mut root = Element::builder("jingle")
+                               .ns(ns::JINGLE)
+                               .attr("action", String::from(self.action.clone()))
+                               .attr("initiator", self.initiator.clone())
+                               .attr("responder", self.responder.clone())
+                               .attr("sid", self.sid.clone())
+                               .build();
+        for content in self.contents.clone() {
+            let content_elem = (&content).into();
+            root.append_child(content_elem);
+        }
+        if let Some(ref reason) = self.reason {
+            let reason2: Element = (&reason.reason).into();
+            let reason_elem = Element::builder("reason")
+                                      .append(reason2)
+                                      .append(reason.text.clone())
+                                      .build();
+            root.append_child(reason_elem);
+        }
+        root
     }
-    if let Some(ref reason) = jingle.reason {
-        let reason_elem = Element::builder("reason")
-                                  .append(reason.reason.clone())
-                                  .append(reason.text.clone())
-                                  .build();
-        root.append_child(reason_elem);
+}
+
+impl Into<Element> for Jingle {
+    fn into(self) -> Element {
+        (&self).into()
     }
-    root
 }
 
 #[cfg(test)]
 mod tests {
-    use minidom::Element;
-    use error::Error;
-    use jingle;
+    use super::*;
 
     #[test]
     fn test_simple() {
         let elem: Element = "<jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' sid='coucou'/>".parse().unwrap();
-        let jingle = jingle::parse_jingle(&elem).unwrap();
-        assert_eq!(jingle.action, jingle::Action::SessionInitiate);
+        let jingle = Jingle::try_from(&elem).unwrap();
+        assert_eq!(jingle.action, Action::SessionInitiate);
         assert_eq!(jingle.sid, "coucou");
     }
 
     #[test]
     fn test_invalid_jingle() {
         let elem: Element = "<jingle xmlns='urn:xmpp:jingle:1'/>".parse().unwrap();
-        let error = jingle::parse_jingle(&elem).unwrap_err();
+        let error = Jingle::try_from(&elem).unwrap_err();
         let message = match error {
             Error::ParseError(string) => string,
             _ => panic!(),
@@ -442,7 +454,7 @@ mod tests {
         assert_eq!(message, "Jingle must have an 'action' attribute.");
 
         let elem: Element = "<jingle xmlns='urn:xmpp:jingle:1' action='session-info'/>".parse().unwrap();
-        let error = jingle::parse_jingle(&elem).unwrap_err();
+        let error = Jingle::try_from(&elem).unwrap_err();
         let message = match error {
             Error::ParseError(string) => string,
             _ => panic!(),
@@ -450,7 +462,7 @@ mod tests {
         assert_eq!(message, "Jingle must have a 'sid' attribute.");
 
         let elem: Element = "<jingle xmlns='urn:xmpp:jingle:1' action='coucou' sid='coucou'/>".parse().unwrap();
-        let error = jingle::parse_jingle(&elem).unwrap_err();
+        let error = Jingle::try_from(&elem).unwrap_err();
         let message = match error {
             Error::ParseError(string) => string,
             _ => panic!(),
@@ -461,25 +473,25 @@ mod tests {
     #[test]
     fn test_content() {
         let elem: Element = "<jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' sid='coucou'><content creator='initiator' name='coucou'><description/><transport/></content></jingle>".parse().unwrap();
-        let jingle = jingle::parse_jingle(&elem).unwrap();
-        assert_eq!(jingle.contents[0].creator, jingle::Creator::Initiator);
+        let jingle = Jingle::try_from(&elem).unwrap();
+        assert_eq!(jingle.contents[0].creator, Creator::Initiator);
         assert_eq!(jingle.contents[0].name, "coucou");
-        assert_eq!(jingle.contents[0].senders, jingle::Senders::Both);
+        assert_eq!(jingle.contents[0].senders, Senders::Both);
         assert_eq!(jingle.contents[0].disposition, "session");
 
         let elem: Element = "<jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' sid='coucou'><content creator='initiator' name='coucou' senders='both'><description/><transport/></content></jingle>".parse().unwrap();
-        let jingle = jingle::parse_jingle(&elem).unwrap();
-        assert_eq!(jingle.contents[0].senders, jingle::Senders::Both);
+        let jingle = Jingle::try_from(&elem).unwrap();
+        assert_eq!(jingle.contents[0].senders, Senders::Both);
 
         let elem: Element = "<jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' sid='coucou'><content creator='initiator' name='coucou' disposition='early-session'><description/><transport/></content></jingle>".parse().unwrap();
-        let jingle = jingle::parse_jingle(&elem).unwrap();
+        let jingle = Jingle::try_from(&elem).unwrap();
         assert_eq!(jingle.contents[0].disposition, "early-session");
     }
 
     #[test]
     fn test_invalid_content() {
         let elem: Element = "<jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' sid='coucou'><content/></jingle>".parse().unwrap();
-        let error = jingle::parse_jingle(&elem).unwrap_err();
+        let error = Jingle::try_from(&elem).unwrap_err();
         let message = match error {
             Error::ParseError(string) => string,
             _ => panic!(),
@@ -487,7 +499,7 @@ mod tests {
         assert_eq!(message, "Content must have a 'creator' attribute.");
 
         let elem: Element = "<jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' sid='coucou'><content creator='initiator'/></jingle>".parse().unwrap();
-        let error = jingle::parse_jingle(&elem).unwrap_err();
+        let error = Jingle::try_from(&elem).unwrap_err();
         let message = match error {
             Error::ParseError(string) => string,
             _ => panic!(),
@@ -495,7 +507,7 @@ mod tests {
         assert_eq!(message, "Content must have a 'name' attribute.");
 
         let elem: Element = "<jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' sid='coucou'><content creator='coucou' name='coucou'/></jingle>".parse().unwrap();
-        let error = jingle::parse_jingle(&elem).unwrap_err();
+        let error = Jingle::try_from(&elem).unwrap_err();
         let message = match error {
             Error::ParseError(string) => string,
             _ => panic!(),
@@ -503,7 +515,7 @@ mod tests {
         assert_eq!(message, "Unknown creator.");
 
         let elem: Element = "<jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' sid='coucou'><content creator='initiator' name='coucou' senders='coucou'/></jingle>".parse().unwrap();
-        let error = jingle::parse_jingle(&elem).unwrap_err();
+        let error = Jingle::try_from(&elem).unwrap_err();
         let message = match error {
             Error::ParseError(string) => string,
             _ => panic!(),
@@ -511,7 +523,7 @@ mod tests {
         assert_eq!(message, "Unknown senders.");
 
         let elem: Element = "<jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' sid='coucou'><content creator='initiator' name='coucou' senders=''/></jingle>".parse().unwrap();
-        let error = jingle::parse_jingle(&elem).unwrap_err();
+        let error = Jingle::try_from(&elem).unwrap_err();
         let message = match error {
             Error::ParseError(string) => string,
             _ => panic!(),
@@ -519,7 +531,7 @@ mod tests {
         assert_eq!(message, "Unknown senders.");
 
         let elem: Element = "<jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' sid='coucou'><content creator='initiator' name='coucou'/></jingle>".parse().unwrap();
-        let error = jingle::parse_jingle(&elem).unwrap_err();
+        let error = Jingle::try_from(&elem).unwrap_err();
         let message = match error {
             Error::ParseError(string) => string,
             _ => panic!(),
@@ -527,7 +539,7 @@ mod tests {
         assert_eq!(message, "Content must have one description.");
 
         let elem: Element = "<jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' sid='coucou'><content creator='initiator' name='coucou'><description/></content></jingle>".parse().unwrap();
-        let error = jingle::parse_jingle(&elem).unwrap_err();
+        let error = Jingle::try_from(&elem).unwrap_err();
         let message = match error {
             Error::ParseError(string) => string,
             _ => panic!(),
@@ -538,22 +550,22 @@ mod tests {
     #[test]
     fn test_reason() {
         let elem: Element = "<jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' sid='coucou'><reason><success/></reason></jingle>".parse().unwrap();
-        let jingle = jingle::parse_jingle(&elem).unwrap();
+        let jingle = Jingle::try_from(&elem).unwrap();
         let reason = jingle.reason.unwrap();
-        assert_eq!(reason.reason, jingle::Reason::Success);
+        assert_eq!(reason.reason, Reason::Success);
         assert_eq!(reason.text, None);
 
         let elem: Element = "<jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' sid='coucou'><reason><success/><text>coucou</text></reason></jingle>".parse().unwrap();
-        let jingle = jingle::parse_jingle(&elem).unwrap();
+        let jingle = Jingle::try_from(&elem).unwrap();
         let reason = jingle.reason.unwrap();
-        assert_eq!(reason.reason, jingle::Reason::Success);
+        assert_eq!(reason.reason, Reason::Success);
         assert_eq!(reason.text, Some(String::from("coucou")));
     }
 
     #[test]
     fn test_invalid_reason() {
         let elem: Element = "<jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' sid='coucou'><reason/></jingle>".parse().unwrap();
-        let error = jingle::parse_jingle(&elem).unwrap_err();
+        let error = Jingle::try_from(&elem).unwrap_err();
         let message = match error {
             Error::ParseError(string) => string,
             _ => panic!(),
@@ -561,7 +573,7 @@ mod tests {
         assert_eq!(message, "Reason doesn’t contain a valid reason.");
 
         let elem: Element = "<jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' sid='coucou'><reason><a/></reason></jingle>".parse().unwrap();
-        let error = jingle::parse_jingle(&elem).unwrap_err();
+        let error = Jingle::try_from(&elem).unwrap_err();
         let message = match error {
             Error::ParseError(string) => string,
             _ => panic!(),
@@ -569,7 +581,7 @@ mod tests {
         assert_eq!(message, "Unknown reason.");
 
         let elem: Element = "<jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' sid='coucou'><reason><a xmlns='http://www.w3.org/1999/xhtml'/></reason></jingle>".parse().unwrap();
-        let error = jingle::parse_jingle(&elem).unwrap_err();
+        let error = Jingle::try_from(&elem).unwrap_err();
         let message = match error {
             Error::ParseError(string) => string,
             _ => panic!(),
@@ -577,7 +589,7 @@ mod tests {
         assert_eq!(message, "Reason contains a foreign element.");
 
         let elem: Element = "<jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' sid='coucou'><reason><decline/></reason><reason/></jingle>".parse().unwrap();
-        let error = jingle::parse_jingle(&elem).unwrap_err();
+        let error = Jingle::try_from(&elem).unwrap_err();
         let message = match error {
             Error::ParseError(string) => string,
             _ => panic!(),
@@ -585,7 +597,7 @@ mod tests {
         assert_eq!(message, "Jingle must not have more than one reason.");
 
         let elem: Element = "<jingle xmlns='urn:xmpp:jingle:1' action='session-initiate' sid='coucou'><reason><decline/><text/><text/></reason></jingle>".parse().unwrap();
-        let error = jingle::parse_jingle(&elem).unwrap_err();
+        let error = Jingle::try_from(&elem).unwrap_err();
         let message = match error {
             Error::ParseError(string) => string,
             _ => panic!(),