status, presence: Merge status into presence.
This commit is contained in:
parent
4b90c1dc1f
commit
0e20810a83
3 changed files with 93 additions and 103 deletions
|
@ -35,8 +35,6 @@ pub mod iq;
|
||||||
|
|
||||||
/// RFC 6121: Extensible Messaging and Presence Protocol (XMPP): Instant Messaging and Presence
|
/// RFC 6121: Extensible Messaging and Presence Protocol (XMPP): Instant Messaging and Presence
|
||||||
pub mod body;
|
pub mod body;
|
||||||
/// RFC 6121: Extensible Messaging and Presence Protocol (XMPP): Instant Messaging and Presence
|
|
||||||
pub mod status;
|
|
||||||
|
|
||||||
/// XEP-0004: Data Forms
|
/// XEP-0004: Data Forms
|
||||||
pub mod data_forms;
|
pub mod data_forms;
|
||||||
|
|
|
@ -15,14 +15,15 @@ use error::Error;
|
||||||
|
|
||||||
use ns;
|
use ns;
|
||||||
|
|
||||||
use status;
|
|
||||||
use delay;
|
use delay;
|
||||||
use ecaps2;
|
use ecaps2;
|
||||||
|
|
||||||
|
pub type Status = String;
|
||||||
|
|
||||||
/// Lists every known payload of a `<presence/>`.
|
/// Lists every known payload of a `<presence/>`.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum PresencePayload {
|
pub enum PresencePayload {
|
||||||
Status(status::Status),
|
Status(Status),
|
||||||
Delay(delay::Delay),
|
Delay(delay::Delay),
|
||||||
ECaps2(ecaps2::ECaps2),
|
ECaps2(ecaps2::ECaps2),
|
||||||
}
|
}
|
||||||
|
@ -112,9 +113,14 @@ pub fn parse_presence(root: &Element) -> Result<Presence, Error> {
|
||||||
};
|
};
|
||||||
let mut payloads = vec!();
|
let mut payloads = vec!();
|
||||||
for elem in root.children() {
|
for elem in root.children() {
|
||||||
let payload = if let Ok(status) = status::parse_status(elem) {
|
if elem.is("status", ns::JABBER_CLIENT) {
|
||||||
Some(PresencePayload::Status(status))
|
for _ in elem.children() {
|
||||||
} else if let Ok(delay) = delay::parse_delay(elem) {
|
return Err(Error::ParseError("Unknown child in status element."));
|
||||||
|
}
|
||||||
|
let payload = PresencePayload::Status(elem.text());
|
||||||
|
payloads.push(PresencePayloadType::Parsed(payload));
|
||||||
|
} else {
|
||||||
|
let payload = if let Ok(delay) = delay::parse_delay(elem) {
|
||||||
Some(PresencePayload::Delay(delay))
|
Some(PresencePayload::Delay(delay))
|
||||||
} else if let Ok(ecaps2) = ecaps2::parse_ecaps2(elem) {
|
} else if let Ok(ecaps2) = ecaps2::parse_ecaps2(elem) {
|
||||||
Some(PresencePayload::ECaps2(ecaps2))
|
Some(PresencePayload::ECaps2(ecaps2))
|
||||||
|
@ -126,6 +132,7 @@ pub fn parse_presence(root: &Element) -> Result<Presence, Error> {
|
||||||
None => PresencePayloadType::XML(elem.clone()),
|
None => PresencePayloadType::XML(elem.clone()),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Ok(Presence {
|
Ok(Presence {
|
||||||
from: from,
|
from: from,
|
||||||
to: to,
|
to: to,
|
||||||
|
@ -137,7 +144,12 @@ pub fn parse_presence(root: &Element) -> Result<Presence, Error> {
|
||||||
|
|
||||||
pub fn serialise_payload(payload: &PresencePayload) -> Element {
|
pub fn serialise_payload(payload: &PresencePayload) -> Element {
|
||||||
match *payload {
|
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::Delay(ref delay) => delay::serialise(delay),
|
||||||
PresencePayload::ECaps2(ref ecaps2) => ecaps2::serialise(ecaps2),
|
PresencePayload::ECaps2(ref ecaps2) => ecaps2::serialise(ecaps2),
|
||||||
}
|
}
|
||||||
|
@ -164,7 +176,9 @@ pub fn serialise(presence: &Presence) -> Element {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use minidom::Element;
|
use minidom::Element;
|
||||||
|
use error::Error;
|
||||||
use presence;
|
use presence;
|
||||||
|
use ns;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_simple() {
|
fn test_simple() {
|
||||||
|
@ -190,4 +204,68 @@ mod tests {
|
||||||
let elem2 = presence::serialise(&presence);
|
let elem2 = presence::serialise(&presence);
|
||||||
assert_eq!(elem, elem2);
|
assert_eq!(elem, elem2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_status() {
|
||||||
|
let elem: Element = "<presence xmlns='jabber:client'><status xmlns='jabber:client'/></presence>".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 = "<presence xmlns='jabber:client'><test xmlns='invalid'/></presence>".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 = "<presence xmlns='jabber:client'><status xmlns='jabber:client'><coucou/></status></presence>".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 = "<status xmlns='jabber:client' coucou=''/>".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::<Vec<_>>()[0].is("status", ns::JABBER_CLIENT));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,86 +0,0 @@
|
||||||
// Copyright (c) 2017 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
|
|
||||||
//
|
|
||||||
// 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<Status, Error> {
|
|
||||||
// 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 = "<status xmlns='jabber:client'/>".parse().unwrap();
|
|
||||||
status::parse_status(&elem).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_invalid() {
|
|
||||||
let elem: Element = "<status xmlns='jabber:server'/>".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 = "<status xmlns='jabber:client'><coucou/></status>".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 = "<status xmlns='jabber:client' coucou=''/>".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));
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue