mirror of
https://gitlab.com/xmpp-rs/xmpp-rs.git
synced 2024-07-12 22:21:53 +00:00
presence: Implement show parsing.
This commit is contained in:
parent
0e20810a83
commit
4ec3898c2f
1 changed files with 80 additions and 3 deletions
|
@ -6,8 +6,8 @@
|
||||||
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use minidom::Element;
|
use minidom::{Element, IntoElements, IntoAttributeValue};
|
||||||
use minidom::IntoAttributeValue;
|
use minidom::convert::ElementEmitter;
|
||||||
|
|
||||||
use jid::Jid;
|
use jid::Jid;
|
||||||
|
|
||||||
|
@ -18,11 +18,32 @@ use ns;
|
||||||
use delay;
|
use delay;
|
||||||
use ecaps2;
|
use ecaps2;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub enum Show {
|
||||||
|
Away,
|
||||||
|
Chat,
|
||||||
|
Dnd,
|
||||||
|
Xa,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoElements for Show {
|
||||||
|
fn into_elements(self, emitter: &mut ElementEmitter) {
|
||||||
|
let elem = Element::builder(match self {
|
||||||
|
Show::Away => "away",
|
||||||
|
Show::Chat => "chat",
|
||||||
|
Show::Dnd => "dnd",
|
||||||
|
Show::Xa => "xa",
|
||||||
|
}).build();
|
||||||
|
emitter.append_child(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub type Status = String;
|
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 {
|
||||||
|
Show(Show),
|
||||||
Status(Status),
|
Status(Status),
|
||||||
Delay(delay::Delay),
|
Delay(delay::Delay),
|
||||||
ECaps2(ecaps2::ECaps2),
|
ECaps2(ecaps2::ECaps2),
|
||||||
|
@ -113,7 +134,20 @@ 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() {
|
||||||
if elem.is("status", ns::JABBER_CLIENT) {
|
if elem.is("show", ns::JABBER_CLIENT) {
|
||||||
|
for _ in elem.children() {
|
||||||
|
return Err(Error::ParseError("Unknown child in show element."));
|
||||||
|
}
|
||||||
|
let payload = PresencePayload::Show(match elem.text().as_ref() {
|
||||||
|
"away" => Show::Away,
|
||||||
|
"chat" => Show::Chat,
|
||||||
|
"dnd" => Show::Dnd,
|
||||||
|
"xa" => Show::Xa,
|
||||||
|
|
||||||
|
_ => return Err(Error::ParseError("Invalid value for show.")),
|
||||||
|
});
|
||||||
|
payloads.push(PresencePayloadType::Parsed(payload));
|
||||||
|
} else if elem.is("status", ns::JABBER_CLIENT) {
|
||||||
for _ in elem.children() {
|
for _ in elem.children() {
|
||||||
return Err(Error::ParseError("Unknown child in status element."));
|
return Err(Error::ParseError("Unknown child in status element."));
|
||||||
}
|
}
|
||||||
|
@ -144,6 +178,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::Show(ref show) => {
|
||||||
|
Element::builder("status")
|
||||||
|
.ns(ns::JABBER_CLIENT)
|
||||||
|
.append(show.to_owned())
|
||||||
|
.build()
|
||||||
|
},
|
||||||
PresencePayload::Status(ref status) => {
|
PresencePayload::Status(ref status) => {
|
||||||
Element::builder("status")
|
Element::builder("status")
|
||||||
.ns(ns::JABBER_CLIENT)
|
.ns(ns::JABBER_CLIENT)
|
||||||
|
@ -205,6 +245,43 @@ mod tests {
|
||||||
assert_eq!(elem, elem2);
|
assert_eq!(elem, elem2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_show() {
|
||||||
|
let elem: Element = "<presence xmlns='jabber:client'><show>chat</show></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::Show(ref show)) => {
|
||||||
|
assert_eq!(*show, presence::Show::Chat);
|
||||||
|
},
|
||||||
|
_ => panic!("Failed to parse show presence."),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_missing_show_value() {
|
||||||
|
// "online" used to be a pretty common mistake.
|
||||||
|
let elem: Element = "<presence xmlns='jabber:client'><show/></presence>".parse().unwrap();
|
||||||
|
let error = presence::parse_presence(&elem).unwrap_err();
|
||||||
|
let message = match error {
|
||||||
|
Error::ParseError(string) => string,
|
||||||
|
_ => panic!(),
|
||||||
|
};
|
||||||
|
assert_eq!(message, "Invalid value for show.");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_invalid_show() {
|
||||||
|
// "online" used to be a pretty common mistake.
|
||||||
|
let elem: Element = "<presence xmlns='jabber:client'><show>online</show></presence>".parse().unwrap();
|
||||||
|
let error = presence::parse_presence(&elem).unwrap_err();
|
||||||
|
let message = match error {
|
||||||
|
Error::ParseError(string) => string,
|
||||||
|
_ => panic!(),
|
||||||
|
};
|
||||||
|
assert_eq!(message, "Invalid value for show.");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_status() {
|
fn test_status() {
|
||||||
let elem: Element = "<presence xmlns='jabber:client'><status xmlns='jabber:client'/></presence>".parse().unwrap();
|
let elem: Element = "<presence xmlns='jabber:client'><status xmlns='jabber:client'/></presence>".parse().unwrap();
|
||||||
|
|
Loading…
Reference in a new issue