Merge branch 'moar-xmpp-parsers' into 'master'
Moar xmpp-parsers See merge request !9
This commit is contained in:
commit
09280ca8df
3 changed files with 59 additions and 106 deletions
|
@ -2,8 +2,9 @@ extern crate xmpp;
|
||||||
|
|
||||||
use xmpp::jid::Jid;
|
use xmpp::jid::Jid;
|
||||||
use xmpp::client::ClientBuilder;
|
use xmpp::client::ClientBuilder;
|
||||||
|
use xmpp::plugins::stanza::StanzaPlugin;
|
||||||
use xmpp::plugins::messaging::{MessagingPlugin, MessageEvent};
|
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 xmpp::plugins::ping::{PingPlugin, PingEvent};
|
||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
|
@ -15,10 +16,11 @@ fn main() {
|
||||||
.password(pass)
|
.password(pass)
|
||||||
.connect()
|
.connect()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
client.register_plugin(StanzaPlugin::new());
|
||||||
client.register_plugin(MessagingPlugin::new());
|
client.register_plugin(MessagingPlugin::new());
|
||||||
client.register_plugin(PresencePlugin::new());
|
client.register_plugin(PresencePlugin::new());
|
||||||
client.register_plugin(PingPlugin::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();
|
client.main().unwrap();
|
||||||
/*loop {
|
/*loop {
|
||||||
let event = client.next_event().unwrap();
|
let event = client.next_event().unwrap();
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
use plugin::PluginProxy;
|
use plugin::PluginProxy;
|
||||||
use event::{Event, Priority, Propagation, ReceiveElement};
|
use event::{Event, Priority, Propagation};
|
||||||
use minidom::Element;
|
|
||||||
use error::Error;
|
use error::Error;
|
||||||
use jid::Jid;
|
use jid::Jid;
|
||||||
use ns;
|
|
||||||
|
use plugins::stanza::Iq;
|
||||||
|
use xmpp_parsers::iq::{IqType, IqPayload};
|
||||||
|
use xmpp_parsers::ping::Ping;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PingEvent {
|
pub struct PingEvent {
|
||||||
pub from: Jid,
|
pub from: Jid,
|
||||||
pub to: Jid,
|
|
||||||
pub id: String,
|
pub id: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,39 +29,43 @@ impl PingPlugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn send_ping(&self, to: &Jid) -> Result<(), Error> {
|
pub fn send_ping(&self, to: &Jid) -> Result<(), Error> {
|
||||||
let mut elem = Element::builder("iq")
|
let to = to.clone();
|
||||||
.attr("type", "get")
|
self.proxy.send(Iq {
|
||||||
.attr("to", to.to_string())
|
from: None,
|
||||||
.build();
|
to: Some(to),
|
||||||
elem.append_child(Element::builder("ping").ns(ns::PING).build());
|
// TODO: use a generic way to generate ids.
|
||||||
self.proxy.send(elem);
|
id: Some(String::from("id")),
|
||||||
|
payload: IqType::Get(IqPayload::Ping(Ping).into()),
|
||||||
|
}.into());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reply_ping(&self, event: &PingEvent) {
|
fn handle_iq(&self, iq: &Iq) -> Propagation {
|
||||||
let reply = Element::builder("iq")
|
let iq = iq.clone();
|
||||||
.attr("type", "result")
|
if let IqType::Get(payload) = iq.payload {
|
||||||
.attr("to", event.from.to_string())
|
// TODO: use an intermediate plugin to parse this payload.
|
||||||
.attr("id", event.id.to_string())
|
if let Ok(IqPayload::Ping(_)) = IqPayload::try_from(payload) {
|
||||||
.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) {
|
|
||||||
self.proxy.dispatch(PingEvent { // TODO: safety!!!
|
self.proxy.dispatch(PingEvent { // TODO: safety!!!
|
||||||
from: elem.attr("from").unwrap().parse().unwrap(),
|
from: iq.from.unwrap(),
|
||||||
to: elem.attr("to").unwrap().parse().unwrap(),
|
id: iq.id.unwrap(),
|
||||||
id: elem.attr("id").unwrap().parse().unwrap(),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Propagation::Continue
|
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, [
|
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 error::Error;
|
||||||
use plugin::PluginProxy;
|
use plugin::PluginProxy;
|
||||||
|
|
||||||
use minidom::Element;
|
pub use xmpp_parsers::presence::{Presence, PresenceType as Type, Show};
|
||||||
|
|
||||||
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 struct PresencePlugin {
|
pub struct PresencePlugin {
|
||||||
proxy: PluginProxy,
|
proxy: PluginProxy,
|
||||||
|
@ -63,33 +16,24 @@ impl PresencePlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_presence(&self, show: Show, status: Option<String>) -> Result<(), Error> {
|
pub fn set_presence(&self, type_: Type, show: Option<Show>, status: Option<String>) -> Result<(), Error> {
|
||||||
if show == Show::Unavailable {
|
let presence = Presence {
|
||||||
self.proxy.send(Element::builder("presence")
|
from: None,
|
||||||
.ns(ns::CLIENT)
|
to: None,
|
||||||
.attr("type", "unavailable")
|
id: None,
|
||||||
.build());
|
type_: type_,
|
||||||
}
|
show: show,
|
||||||
else {
|
priority: 0i8,
|
||||||
let mut stanza = Element::builder("presence")
|
statuses: {
|
||||||
.ns(ns::CLIENT)
|
let mut statuses = BTreeMap::new();
|
||||||
.build();
|
if let Some(status) = status {
|
||||||
if let Some(stat) = status {
|
statuses.insert(String::new(), 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);
|
|
||||||
}
|
}
|
||||||
|
statuses
|
||||||
|
},
|
||||||
|
payloads: vec!(),
|
||||||
|
};
|
||||||
|
self.proxy.send(presence.into());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue