presence.rs

 1use error::Error;
 2use plugin::PluginProxy;
 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!(PresencePlugin, proxy, []);