diff --git a/src/lib.rs b/src/lib.rs index aadf4f79..0a5eac0a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -35,8 +35,6 @@ pub mod iq; /// RFC 6121: Extensible Messaging and Presence Protocol (XMPP): Instant Messaging and Presence pub mod body; -/// RFC 6121: Extensible Messaging and Presence Protocol (XMPP): Instant Messaging and Presence -pub mod status; /// XEP-0004: Data Forms pub mod data_forms; diff --git a/src/presence.rs b/src/presence.rs index 0f437958..cafb7f6e 100644 --- a/src/presence.rs +++ b/src/presence.rs @@ -15,14 +15,15 @@ use error::Error; use ns; -use status; use delay; use ecaps2; +pub type Status = String; + /// Lists every known payload of a ``. #[derive(Debug, Clone)] pub enum PresencePayload { - Status(status::Status), + Status(Status), Delay(delay::Delay), ECaps2(ecaps2::ECaps2), } @@ -112,19 +113,25 @@ pub fn parse_presence(root: &Element) -> Result { }; let mut payloads = vec!(); for elem in root.children() { - let payload = if let Ok(status) = status::parse_status(elem) { - Some(PresencePayload::Status(status)) - } else if let Ok(delay) = delay::parse_delay(elem) { - Some(PresencePayload::Delay(delay)) - } else if let Ok(ecaps2) = ecaps2::parse_ecaps2(elem) { - Some(PresencePayload::ECaps2(ecaps2)) + if elem.is("status", ns::JABBER_CLIENT) { + for _ in elem.children() { + return Err(Error::ParseError("Unknown child in status element.")); + } + let payload = PresencePayload::Status(elem.text()); + payloads.push(PresencePayloadType::Parsed(payload)); } else { - None - }; - payloads.push(match payload { - Some(payload) => PresencePayloadType::Parsed(payload), - None => PresencePayloadType::XML(elem.clone()), - }); + let payload = if let Ok(delay) = delay::parse_delay(elem) { + Some(PresencePayload::Delay(delay)) + } else if let Ok(ecaps2) = ecaps2::parse_ecaps2(elem) { + Some(PresencePayload::ECaps2(ecaps2)) + } else { + None + }; + payloads.push(match payload { + Some(payload) => PresencePayloadType::Parsed(payload), + None => PresencePayloadType::XML(elem.clone()), + }); + } } Ok(Presence { from: from, @@ -137,7 +144,12 @@ pub fn parse_presence(root: &Element) -> Result { pub fn serialise_payload(payload: &PresencePayload) -> Element { match *payload { - PresencePayload::Status(ref status) => status::serialise(status), + PresencePayload::Status(ref status) => { + Element::builder("status") + .ns(ns::JABBER_CLIENT) + .append(status.to_owned()) + .build() + }, PresencePayload::Delay(ref delay) => delay::serialise(delay), PresencePayload::ECaps2(ref ecaps2) => ecaps2::serialise(ecaps2), } @@ -164,7 +176,9 @@ pub fn serialise(presence: &Presence) -> Element { #[cfg(test)] mod tests { use minidom::Element; + use error::Error; use presence; + use ns; #[test] fn test_simple() { @@ -190,4 +204,68 @@ mod tests { let elem2 = presence::serialise(&presence); assert_eq!(elem, elem2); } + + #[test] + fn test_status() { + let elem: Element = "".parse().unwrap(); + let presence = presence::parse_presence(&elem).unwrap(); + assert_eq!(presence.payloads.len(), 1); + match presence.payloads[0] { + presence::PresencePayloadType::Parsed(presence::PresencePayload::Status(ref status)) => { + assert_eq!(*status, presence::Status::from("")); + }, + _ => panic!("Failed to parse status presence."), + } + } + + #[test] + fn test_unknown_child() { + let elem: Element = "".parse().unwrap(); + let presence = presence::parse_presence(&elem).unwrap(); + if let presence::PresencePayloadType::XML(ref payload) = presence.payloads[0] { + assert!(payload.is("test", "invalid")); + } else { + panic!("Did successfully parse an invalid element."); + } + } + + #[test] + #[ignore] + fn test_invalid_status_child() { + let elem: Element = "".parse().unwrap(); + let error = presence::parse_presence(&elem).unwrap_err(); + let message = match error { + Error::ParseError(string) => string, + _ => panic!(), + }; + assert_eq!(message, "Unknown child in status element."); + } + + #[test] + #[ignore] + fn test_invalid_attribute() { + let elem: Element = "".parse().unwrap(); + let error = presence::parse_presence(&elem).unwrap_err(); + let message = match error { + Error::ParseError(string) => string, + _ => panic!(), + }; + assert_eq!(message, "Unknown attribute in status element."); + } + + #[test] + fn test_serialise_status() { + let status = presence::Status::from("Hello world!"); + let payloads = vec!(presence::PresencePayloadType::Parsed(presence::PresencePayload::Status(status))); + let presence = presence::Presence { + from: None, + to: None, + id: None, + type_: presence::PresenceType::Unavailable, + payloads: payloads, + }; + let elem = presence::serialise(&presence); + assert!(elem.is("presence", ns::JABBER_CLIENT)); + assert!(elem.children().collect::>()[0].is("status", ns::JABBER_CLIENT)); + } } diff --git a/src/status.rs b/src/status.rs deleted file mode 100644 index 66bde73e..00000000 --- a/src/status.rs +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (c) 2017 Emmanuel Gil Peyrot -// -// This Source Code Form is subject to the terms of the Mozilla Public -// 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 minidom::Element; - -use error::Error; - -use ns; - -pub type Status = String; - -pub fn parse_status(root: &Element) -> Result { - // TODO: also support components and servers. - if !root.is("status", ns::JABBER_CLIENT) { - return Err(Error::ParseError("This is not a status element.")); - } - for _ in root.children() { - return Err(Error::ParseError("Unknown child in status element.")); - } - Ok(root.text()) -} - -pub fn serialise(status: &Status) -> Element { - Element::builder("status") - .ns(ns::JABBER_CLIENT) - .append(status.to_owned()) - .build() -} - -#[cfg(test)] -mod tests { - use minidom::Element; - use error::Error; - use status; - use ns; - - #[test] - fn test_simple() { - let elem: Element = "".parse().unwrap(); - status::parse_status(&elem).unwrap(); - } - - #[test] - fn test_invalid() { - let elem: Element = "".parse().unwrap(); - let error = status::parse_status(&elem).unwrap_err(); - let message = match error { - Error::ParseError(string) => string, - _ => panic!(), - }; - assert_eq!(message, "This is not a status element."); - } - - #[test] - fn test_invalid_child() { - let elem: Element = "".parse().unwrap(); - let error = status::parse_status(&elem).unwrap_err(); - let message = match error { - Error::ParseError(string) => string, - _ => panic!(), - }; - assert_eq!(message, "Unknown child in status element."); - } - - #[test] - #[ignore] - fn test_invalid_attribute() { - let elem: Element = "".parse().unwrap(); - let error = status::parse_status(&elem).unwrap_err(); - let message = match error { - Error::ParseError(string) => string, - _ => panic!(), - }; - assert_eq!(message, "Unknown attribute in status element."); - } - - #[test] - fn test_serialise() { - let status = status::Status::from("Hello world!"); - let elem = status::serialise(&status); - assert!(elem.is("status", ns::JABBER_CLIENT)); - } -}