presence.rs

  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}