@@ -2,8 +2,9 @@ extern crate xmpp;
use xmpp::jid::Jid;
use xmpp::client::ClientBuilder;
+use xmpp::plugins::stanza::StanzaPlugin;
use xmpp::plugins::messaging::{MessagingPlugin, MessageEvent};
-use xmpp::plugins::presence::{PresencePlugin, Show};
+use xmpp::plugins::presence::{PresencePlugin, Type};
use xmpp::plugins::ping::{PingPlugin, PingEvent};
use std::env;
@@ -15,10 +16,11 @@ fn main() {
.password(pass)
.connect()
.unwrap();
+ client.register_plugin(StanzaPlugin::new());
client.register_plugin(MessagingPlugin::new());
client.register_plugin(PresencePlugin::new());
client.register_plugin(PingPlugin::new());
- client.plugin::<PresencePlugin>().set_presence(Show::Available, None).unwrap();
+ client.plugin::<PresencePlugin>().set_presence(Type::Available, None, None).unwrap();
client.main().unwrap();
/*loop {
let event = client.next_event().unwrap();
@@ -1,14 +1,17 @@
+use std::convert::TryFrom;
+
use plugin::PluginProxy;
-use event::{Event, Priority, Propagation, ReceiveElement};
-use minidom::Element;
+use event::{Event, Priority, Propagation};
use error::Error;
use jid::Jid;
-use ns;
+
+use plugins::stanza::Iq;
+use xmpp_parsers::iq::{IqType, IqPayload};
+use xmpp_parsers::ping::Ping;
#[derive(Debug)]
pub struct PingEvent {
pub from: Jid,
- pub to: Jid,
pub id: String,
}
@@ -26,39 +29,43 @@ impl PingPlugin {
}
pub fn send_ping(&self, to: &Jid) -> Result<(), Error> {
- let mut elem = Element::builder("iq")
- .attr("type", "get")
- .attr("to", to.to_string())
- .build();
- elem.append_child(Element::builder("ping").ns(ns::PING).build());
- self.proxy.send(elem);
+ let to = to.clone();
+ self.proxy.send(Iq {
+ from: None,
+ to: Some(to),
+ // TODO: use a generic way to generate ids.
+ id: Some(String::from("id")),
+ payload: IqType::Get(IqPayload::Ping(Ping).into()),
+ }.into());
Ok(())
}
- pub fn reply_ping(&self, event: &PingEvent) {
- let reply = Element::builder("iq")
- .attr("type", "result")
- .attr("to", event.from.to_string())
- .attr("id", event.id.to_string())
- .build();
- self.proxy.send(reply);
- }
-
- fn handle_receive_element(&self, evt: &ReceiveElement) -> Propagation {
- let elem = &evt.0;
- if elem.is("iq", ns::CLIENT) && elem.attr("type") == Some("get") {
- if elem.has_child("ping", ns::PING) {
+ fn handle_iq(&self, iq: &Iq) -> Propagation {
+ let iq = iq.clone();
+ if let IqType::Get(payload) = iq.payload {
+ // TODO: use an intermediate plugin to parse this payload.
+ if let Ok(IqPayload::Ping(_)) = IqPayload::try_from(payload) {
self.proxy.dispatch(PingEvent { // TODO: safety!!!
- from: elem.attr("from").unwrap().parse().unwrap(),
- to: elem.attr("to").unwrap().parse().unwrap(),
- id: elem.attr("id").unwrap().parse().unwrap(),
+ from: iq.from.unwrap(),
+ id: iq.id.unwrap(),
});
}
}
Propagation::Continue
}
+
+ fn reply_ping(&self, ping: &PingEvent) -> Propagation {
+ self.proxy.send(Iq {
+ from: None,
+ to: Some(ping.from.to_owned()),
+ id: Some(ping.id.to_owned()),
+ payload: IqType::Result(None),
+ }.into());
+ Propagation::Continue
+ }
}
impl_plugin!(PingPlugin, proxy, [
- (ReceiveElement, Priority::Default) => handle_receive_element,
+ (Iq, Priority::Default) => handle_iq,
+ (PingEvent, Priority::Default) => reply_ping,
]);
@@ -1,56 +1,9 @@
+use std::collections::BTreeMap;
+
use error::Error;
use plugin::PluginProxy;
-use minidom::Element;
-
-use ns;
-
-use std::fmt;
-
-use std::str::FromStr;
-
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
-pub enum Show {
- Available,
- Away,
- ExtendedAway,
- DoNotDisturb,
- Chat,
- Unavailable,
-}
-
-impl fmt::Display for Show {
- fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- match *self {
- Show::Away => write!(fmt, "away"),
- Show::ExtendedAway => write!(fmt, "xa"),
- Show::DoNotDisturb => write!(fmt, "dnd"),
- Show::Chat => write!(fmt, "chat"),
-
- // will never be seen inside a <show>, maybe should crash?
- Show::Available => write!(fmt, "available"),
- Show::Unavailable => write!(fmt, "unavailable"),
- }
- }
-}
-
-#[derive(Debug, Copy, Clone, PartialEq, Eq)]
-pub struct InvalidShow;
-
-impl FromStr for Show {
- type Err = InvalidShow;
-
- fn from_str(s: &str) -> Result<Show, InvalidShow> {
- Ok(match s {
- "away" => Show::Away,
- "xa" => Show::ExtendedAway,
- "dnd" => Show::DoNotDisturb,
- "chat" => Show::Chat,
-
- _ => { return Err(InvalidShow); }
- })
- }
-}
+pub use xmpp_parsers::presence::{Presence, PresenceType as Type, Show};
pub struct PresencePlugin {
proxy: PluginProxy,
@@ -63,33 +16,24 @@ impl PresencePlugin {
}
}
- pub fn set_presence(&self, show: Show, status: Option<String>) -> Result<(), Error> {
- if show == Show::Unavailable {
- self.proxy.send(Element::builder("presence")
- .ns(ns::CLIENT)
- .attr("type", "unavailable")
- .build());
- }
- else {
- let mut stanza = Element::builder("presence")
- .ns(ns::CLIENT)
- .build();
- if let Some(stat) = status {
- let elem = Element::builder("status")
- .ns(ns::CLIENT)
- .append(stat)
- .build();
- stanza.append_child(elem);
- }
- let mut elem = Element::builder("show")
- .ns(ns::CLIENT)
- .build();
- if show != Show::Available {
- elem.append_text_node(show.to_string());
- }
- stanza.append_child(elem);
- self.proxy.send(stanza);
- }
+ pub fn set_presence(&self, type_: Type, show: Option<Show>, status: Option<String>) -> Result<(), Error> {
+ let presence = Presence {
+ from: None,
+ to: None,
+ id: None,
+ type_: type_,
+ show: show,
+ priority: 0i8,
+ statuses: {
+ let mut statuses = BTreeMap::new();
+ if let Some(status) = status {
+ statuses.insert(String::new(), status);
+ }
+ statuses
+ },
+ payloads: vec!(),
+ };
+ self.proxy.send(presence.into());
Ok(())
}
}