1use std::convert::TryFrom;
2
3use plugin::PluginProxy;
4use event::{Event, Priority, Propagation};
5use error::Error;
6use jid::Jid;
7
8use plugins::stanza::Iq;
9use xmpp_parsers::iq::{IqType, IqPayload};
10use xmpp_parsers::ping::Ping;
11
12#[derive(Debug)]
13pub struct PingEvent {
14 pub from: Jid,
15 pub id: String,
16}
17
18impl Event for PingEvent {}
19
20pub struct PingPlugin {
21 proxy: PluginProxy,
22}
23
24impl PingPlugin {
25 pub fn new() -> PingPlugin {
26 PingPlugin {
27 proxy: PluginProxy::new(),
28 }
29 }
30
31 pub fn send_ping(&self, to: &Jid) -> Result<(), Error> {
32 let to = to.clone();
33 self.proxy.send(Iq {
34 from: None,
35 to: Some(to),
36 // TODO: use a generic way to generate ids.
37 id: Some(String::from("id")),
38 payload: IqType::Get(IqPayload::Ping(Ping).into()),
39 }.into());
40 Ok(())
41 }
42
43 fn handle_iq(&self, iq: &Iq) -> Propagation {
44 let iq = iq.clone();
45 if let IqType::Get(payload) = iq.payload {
46 // TODO: use an intermediate plugin to parse this payload.
47 if let Ok(IqPayload::Ping(_)) = IqPayload::try_from(payload) {
48 self.proxy.dispatch(PingEvent { // TODO: safety!!!
49 from: iq.from.unwrap(),
50 id: iq.id.unwrap(),
51 });
52 return Propagation::Stop;
53 }
54 }
55 Propagation::Continue
56 }
57
58 fn reply_ping(&self, ping: &PingEvent) -> Propagation {
59 self.proxy.send(Iq {
60 from: None,
61 to: Some(ping.from.to_owned()),
62 id: Some(ping.id.to_owned()),
63 payload: IqType::Result(None),
64 }.into());
65 Propagation::Continue
66 }
67}
68
69impl_plugin!(PingPlugin, proxy, [
70 (Iq, Priority::Default) => handle_iq,
71 (PingEvent, Priority::Default) => reply_ping,
72]);