summaryrefslogtreecommitdiff
path: root/src/sock.rs
diff options
context:
space:
mode:
authorYorhel <git@yorhel.nl>2019-04-18 15:44:17 +0200
committerYorhel <git@yorhel.nl>2019-04-18 15:44:17 +0200
commitcb642ff75eb1fdfa5ec0d944ef4a148eed54f761 (patch)
tree46935c5817a390c8d40c80687d05568ee255e455 /src/sock.rs
parent6b37deeec4e1caf77e242b85ae2dc4af521ceeea (diff)
Fixup async event infrastructure + allow receiving log events
Diffstat (limited to 'src/sock.rs')
-rw-r--r--src/sock.rs61
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))
+ }
}
}