1use error::Error;
2use plugin::{Plugin, PluginProxy, PluginReturn};
3
4use minidom::Element;
5
6use ns;
7
8use std::fmt;
9
10use std::str::FromStr;
11
12#[derive(Debug, Copy, Clone, PartialEq, Eq)]
13pub enum Show {
14 Available,
15 Away,
16 ExtendedAway,
17 DoNotDisturb,
18 Chat,
19 Unavailable,
20}
21
22impl fmt::Display for Show {
23 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
24 match *self {
25 Show::Away => write!(fmt, "away"),
26 Show::ExtendedAway => write!(fmt, "xa"),
27 Show::DoNotDisturb => write!(fmt, "dnd"),
28 Show::Chat => write!(fmt, "chat"),
29
30 // will never be seen inside a <show>, maybe should crash?
31 Show::Available => write!(fmt, "available"),
32 Show::Unavailable => write!(fmt, "unavailable"),
33 }
34 }
35}
36
37#[derive(Debug, Copy, Clone, PartialEq, Eq)]
38pub struct InvalidShow;
39
40impl FromStr for Show {
41 type Err = InvalidShow;
42
43 fn from_str(s: &str) -> Result<Show, InvalidShow> {
44 Ok(match s {
45 "away" => Show::Away,
46 "xa" => Show::ExtendedAway,
47 "dnd" => Show::DoNotDisturb,
48 "chat" => Show::Chat,
49
50 _ => { return Err(InvalidShow); }
51 })
52 }
53}
54
55pub struct PresencePlugin {
56 proxy: PluginProxy,
57}
58
59impl PresencePlugin {
60 pub fn new() -> PresencePlugin {
61 PresencePlugin {
62 proxy: PluginProxy::new(),
63 }
64 }
65
66 pub fn set_presence(&self, show: Show, status: Option<String>) -> Result<(), Error> {
67 if show == Show::Unavailable {
68 self.proxy.send(Element::builder("presence")
69 .ns(ns::CLIENT)
70 .attr("type", "unavailable")
71 .build());
72 }
73 else {
74 let mut stanza = Element::builder("presence")
75 .ns(ns::CLIENT)
76 .build();
77 if let Some(stat) = status {
78 let elem = Element::builder("status")
79 .ns(ns::CLIENT)
80 .append(stat)
81 .build();
82 stanza.append_child(elem);
83 }
84 let mut elem = Element::builder("show")
85 .ns(ns::CLIENT)
86 .build();
87 if show != Show::Available {
88 elem.append_text_node(show.to_string());
89 }
90 stanza.append_child(elem);
91 self.proxy.send(stanza);
92 }
93 Ok(())
94 }
95}
96
97impl Plugin for PresencePlugin {
98 fn get_proxy(&mut self) -> &mut PluginProxy {
99 &mut self.proxy
100 }
101
102 fn handle(&mut self, _elem: &Element) -> PluginReturn {
103 PluginReturn::Continue
104 }
105}