1use try_from::TryFrom;
2
3use plugin::PluginProxy;
4use event::{Event, Priority, Propagation};
5use error::Error;
6use jid::Jid;
7
8use plugins::stanza::Iq;
9use plugins::disco::DiscoPlugin;
10use xmpp_parsers::iq::{IqType, IqGetPayload};
11use xmpp_parsers::ping::Ping;
12use xmpp_parsers::ns;
13
14#[derive(Debug)]
15pub struct PingEvent {
16 pub from: Jid,
17 pub id: String,
18}
19
20impl Event for PingEvent {}
21
22pub struct PingPlugin {
23 proxy: PluginProxy,
24}
25
26impl PingPlugin {
27 pub fn new() -> PingPlugin {
28 PingPlugin {
29 proxy: PluginProxy::new(),
30 }
31 }
32
33 // TODO: make that called automatically after plugins are created.
34 pub fn init(&self) {
35 if let Some(disco) = self.proxy.plugin::<DiscoPlugin>() {
36 disco.add_feature(ns::PING);
37 } else {
38 panic!("Please handle dependencies in the correct order.");
39 }
40 }
41
42 // TODO: make that called automatically before removal.
43 pub fn deinit(&self) {
44 if let Some(disco) = self.proxy.plugin::<DiscoPlugin>() {
45 disco.remove_feature(ns::PING);
46 } else {
47 panic!("Please handle dependencies in the correct order.");
48 }
49 }
50
51 pub fn send_ping(&self, to: &Jid) -> Result<(), Error> {
52 let to = to.clone();
53 self.proxy.send(Iq {
54 from: None,
55 to: Some(to),
56 id: Some(self.proxy.gen_id()),
57 payload: IqType::Get(IqGetPayload::Ping(Ping).into()),
58 }.into());
59 Ok(())
60 }
61
62 fn handle_iq(&self, iq: &Iq) -> Propagation {
63 let iq = iq.clone();
64 if let IqType::Get(payload) = iq.payload {
65 // TODO: use an intermediate plugin to parse this payload.
66 if let Ok(IqGetPayload::Ping(_)) = IqGetPayload::try_from(payload) {
67 self.proxy.dispatch(PingEvent { // TODO: safety!!!
68 from: iq.from.unwrap(),
69 id: iq.id.unwrap(),
70 });
71 return Propagation::Stop;
72 }
73 }
74 Propagation::Continue
75 }
76
77 fn reply_ping(&self, ping: &PingEvent) -> Propagation {
78 self.proxy.send(Iq {
79 from: None,
80 to: Some(ping.from.to_owned()),
81 id: Some(ping.id.to_owned()),
82 payload: IqType::Result(None),
83 }.into());
84 Propagation::Continue
85 }
86}
87
88impl_plugin!(PingPlugin, proxy, [
89 (Iq, Priority::Default) => handle_iq,
90 (PingEvent, Priority::Default) => reply_ping,
91]);