diff options
Diffstat (limited to 'src/sock.rs')
-rw-r--r-- | src/sock.rs | 72 |
1 files changed, 46 insertions, 26 deletions
diff --git a/src/sock.rs b/src/sock.rs index faccb46..42a5d90 100644 --- a/src/sock.rs +++ b/src/sock.rs @@ -164,6 +164,26 @@ pub struct BootstrapStatus { // TODO: warning/reason/count/recommendation } +impl BootstrapStatus { + // Parses the part after the severity and "BOOTSTRAP " string. + fn parse(sev: Severity, buf: &mut &str) -> Result<Box<BootstrapStatus>> { + let mut bs = Box::new(BootstrapStatus { + severity: sev, + progress: 0, + tag: String::new(), + summary: String::new(), + }); + // TODO: Can the order of these arguments change? + cons(buf, "PROGRESS=")?; + bs.progress = cons_u8(buf)?; + cons(buf, " TAG=")?; + bs.tag = cons_keyword(buf)?.to_owned(); + cons(buf, " SUMMARY=")?; + bs.summary = QuotedString::parse(buf)?; + Ok(bs) + } +} + /// Tor log message severity. #[derive(Debug,PartialEq,Eq,PartialOrd,Ord,Clone,Copy)] @@ -175,6 +195,17 @@ pub enum Severity { Err } +impl Severity { + fn parse(buf: &mut &str) -> Result<Severity> { + if cons(buf, "DEBUG" ).is_ok() { Ok(Severity::Debug ) } + else if cons(buf, "INFO" ).is_ok() { Ok(Severity::Info ) } + else if cons(buf, "NOTICE").is_ok() { Ok(Severity::Notice) } + else if cons(buf, "WARN" ).is_ok() { Ok(Severity::Warn ) } + else if cons(buf, "ERR" ).is_ok() { Ok(Severity::Err ) } + else { Err(err!(Parse)) } + } +} + /// An asynchronous event received from Tor. These are returned by `read_event()`. #[derive(Debug)] @@ -543,27 +574,29 @@ impl Sock { Ok(res) } + /// Returns the latest bootstrap status. This is a convenience wrapper around + /// `getinfo(&["status/bootstrap-phase"])`. + pub fn bootstrap_status(&self) -> Result<Box<BootstrapStatus>> { + let ret = self.getinfo(&["status/bootstrap-phase"])?; + let mut buf = &ret[0].1[..]; + let sev = Severity::parse(&mut buf)?; + cons(&mut buf, " BOOTSTRAP ")?; + BootstrapStatus::parse(sev, &mut buf) + } + pub fn setevents(&self, events: EventList) -> Result<()> { self.cmd(events.cmd()).map(|_|()) } /// Read an event from the socket. This method blocks until an event has been received. + // TODO: Differentiate between fatal and temporary errors. pub fn read_event(&self) -> Result<Event> { - fn extract_sev(buf: &mut &str) -> Result<Severity> { - if cons(buf, "DEBUG " ).is_ok() { Ok(Severity::Debug ) } - else if cons(buf, "INFO " ).is_ok() { Ok(Severity::Info ) } - else if cons(buf, "NOTICE ").is_ok() { Ok(Severity::Notice) } - else if cons(buf, "WARN " ).is_ok() { Ok(Severity::Warn ) } - else if cons(buf, "ERR " ).is_ok() { Ok(Severity::Err ) } - else { Err(err!(Parse)) } - } - loop { let mut ret = self.get_reply(true)?; let ev = ret.remove(0); let mut buf = &ev.text[..]; - if let Ok(sev) = extract_sev(&mut buf) { + if let Ok(sev) = Severity::parse(&mut buf) { let s = if ev.data.is_empty() { buf.trim().to_owned() } else { @@ -572,22 +605,9 @@ impl Sock { return Ok(Event::Log(sev, s)) } else if cons(&mut buf, "STATUS_CLIENT ").is_ok() { - let sev = extract_sev(&mut buf)?; - if cons(&mut buf, "BOOTSTRAP ").is_ok() { - let mut bs = Box::new(BootstrapStatus { - severity: sev, - progress: 0, - tag: String::new(), - summary: String::new(), - }); - // TODO: Can the order of these arguments change? - cons(&mut buf, "PROGRESS=")?; - bs.progress = cons_u8(&mut buf)?; - cons(&mut buf, " TAG=")?; - bs.tag = cons_keyword(&mut buf)?.to_owned(); - cons(&mut buf, " SUMMARY=")?; - bs.summary = QuotedString::parse(&mut buf)?; - return Ok(Event::Bootstrap(bs)) + let sev = Severity::parse(&mut buf)?; + if cons(&mut buf, " BOOTSTRAP ").is_ok() { + return Ok(Event::Bootstrap(BootstrapStatus::parse(sev, &mut buf)?)) } } } |