1use std::collections::BTreeMap;
2use try_from::TryFrom;
3
4use jid::Jid;
5use error::Error;
6use plugin::PluginProxy;
7
8use event::{Event, Propagation, Priority};
9
10pub use xmpp_parsers::muc::{Muc, MucUser};
11pub use xmpp_parsers::muc::user::{Status, Affiliation, Role};
12pub use xmpp_parsers::presence::{Presence, Type, Show};
13
14#[derive(Debug)]
15pub struct MucPresence {
16 pub room: Jid,
17 pub nick: Option<String>,
18 pub to: Jid,
19 pub type_: Type,
20 pub x: MucUser,
21}
22
23impl Event for MucPresence {}
24
25pub struct MucPlugin {
26 proxy: PluginProxy,
27}
28
29impl MucPlugin {
30 pub fn new() -> MucPlugin {
31 MucPlugin {
32 proxy: PluginProxy::new(),
33 }
34 }
35
36 pub fn join_room(&self, room: Jid) -> Result<(), Error> {
37 let x = Muc { password: None };
38 let presence = Presence {
39 from: None,
40 to: Some(room),
41 id: None,
42 type_: Type::None,
43 show: Show::None,
44 priority: 0i8,
45 statuses: BTreeMap::new(),
46 payloads: vec![x.into()],
47 };
48 self.proxy.send(presence.into());
49
50 Ok(())
51 }
52
53 pub fn leave_room(&self, room: Jid) -> Result<(), Error> {
54 let x = Muc { password: None };
55 let presence = Presence {
56 from: None,
57 to: Some(room),
58 id: None,
59 type_: Type::None,
60 show: Show::None,
61 priority: 0i8,
62 statuses: BTreeMap::new(),
63 payloads: vec![x.into()],
64 };
65 self.proxy.send(presence.into());
66 Ok(())
67 }
68
69 fn handle_presence(&self, presence: &Presence) -> Propagation {
70 let from = presence.from.clone().unwrap();
71 let room = from.clone().into_bare_jid();
72 let nick = from.resource;
73 let to = presence.to.clone().unwrap();
74 let type_ = presence.type_.clone();
75
76 for payload in presence.clone().payloads {
77 if let Ok(x) = MucUser::try_from(payload) {
78 self.proxy.dispatch(MucPresence {
79 room: room.clone(),
80 nick: nick.clone(),
81 to: to.clone(),
82 type_: type_.clone(),
83 x
84 });
85 }
86 }
87
88 Propagation::Stop
89 }
90}
91
92impl_plugin!(MucPlugin, proxy, [
93 (Presence, Priority::Default) => handle_presence,
94]);