diff options
Diffstat (limited to 'src/sock.rs')
-rw-r--r-- | src/sock.rs | 61 |
1 files changed, 45 insertions, 16 deletions
diff --git a/src/sock.rs b/src/sock.rs index 8102ebc..1724509 100644 --- a/src/sock.rs +++ b/src/sock.rs @@ -123,6 +123,16 @@ pub enum Auth { } +#[derive(Debug)] +pub enum Event { + // Log messages + Debug(String), + Info(String), + Notice(String), + Warn(String), + Err(String), +} + // A double-quoted string where only \ and " are escaped. @@ -356,8 +366,6 @@ impl Sock { // XXX: This IntoIterator works with &[..] and &vec![..]. Haven't tested HashMap/BTreeMap yet, // but I suspect their signature doesn't match. - // Warning: There's no validation on the key string format, so this command allows protocol - // injection. fn setresetconf<'a,T>(&self, mut msg: String, settings: T) -> Result<()> where T: IntoIterator<Item = &'a (&'a str, Option<&'a str>)>, { @@ -451,24 +459,45 @@ impl Sock { Ok(res) } - pub fn events(&'a self, list: ..) -> Result<Events<'a>> { + // TODO: Create an enum for supported event types, rather than this string thing. We don't + // support reading all types of events anyway. + pub fn setevents<'a,T: IntoIterator<Item = &'a &'a str>>(&self, events: T) -> Result<()> { + let mut msg = "SETEVENTS".to_string(); + for e in events { + is_keyword(e)?; + msg.push(' '); + msg.push_str(e); + } + msg.push_str("\r\n"); + self.cmd(msg).map(|_|()) } -} + /// Read an event from the socket. This method blocks until an event has been received. + pub fn read_event(&self) -> Result<Event> { + let mut ret = self.get_reply(true)?; + let ev = ret.remove(0); -pub struct Events<'a> { - sock: &'a Sock -} - -impl<'a> Drop for Events<'a> { - fn drop(&mut self) { - self.sock.cmd("SETEVENTS\r\n").is_ok(); - } -} + fn logmsg(r: ReplyLine, skip: usize) -> String { + if r.data.is_empty() { + (&r.text[skip..]).trim().to_owned() + } else { + String::from_utf8_lossy(&r.data).trim().to_owned() + } + } -impl<'a> Iterator for Events<'a> { - type Item = Result<Event>; - fn next(&mut self) -> Option<Self::Item> { + if ev.status == 650 && ev.text.starts_with("DEBUG") { + Ok(Event::Debug(logmsg(ev, 6))) + } else if ev.status == 650 && ev.text.starts_with("NOTICE") { + Ok(Event::Notice(logmsg(ev, 7))) + } else if ev.status == 650 && ev.text.starts_with("INFO") { + Ok(Event::Info(logmsg(ev, 5))) + } else if ev.status == 650 && ev.text.starts_with("WARN") { + Ok(Event::Warn(logmsg(ev, 5))) + } else if ev.status == 650 && ev.text.starts_with("ERR") { + Ok(Event::Err(logmsg(ev, 4))) + } else { + Err(err!(UnknownEvent, ev.text)) + } } } |