From 50058305a9505e18678292e9f4b9b1dc17cd3949 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Tue, 9 Sep 2014 17:41:24 -0400 Subject: propagate a few more errors --- examples/client.rs | 9 ++-- src/client.rs | 146 +++++++++++++++++++++++++++++------------------------ src/message.rs | 19 ++++--- 3 files changed, 96 insertions(+), 78 deletions(-) diff --git a/examples/client.rs b/examples/client.rs index 5b874bb..0794329 100644 --- a/examples/client.rs +++ b/examples/client.rs @@ -2,19 +2,22 @@ extern crate irc; use irc::constants::Pong; +use std::io; + pub struct ExampleClient; impl irc::ClientCallbacks for ExampleClient { - fn on_any_message (&mut self, _client: &mut irc::Client, m: &irc::Message) { + fn on_any_message (&mut self, _client: &mut irc::Client, m: &irc::Message) -> io::IoResult<()> { print!("{}", m.to_protocol_string()); + Ok(()) } - fn on_ping (&mut self, client: &mut irc::Client, _from: Option<&str>, server1: &str, server2: Option<&str>) { + fn on_ping (&mut self, client: &mut irc::Client, _from: Option<&str>, server1: &str, server2: Option<&str>) -> io::IoResult<()> { let params = match server2 { Some(server2) => vec![server1.to_string(), server2.to_string()], None => vec![server1.to_string()], }; - client.write(irc::Message::new(None, Pong, params)); + client.write(irc::Message::new(None, Pong, params)) } } diff --git a/src/client.rs b/src/client.rs index b98471b..bddeb47 100644 --- a/src/client.rs +++ b/src/client.rs @@ -142,18 +142,22 @@ impl Client { Message::parse(str::from_utf8(buf.unwrap().as_slice()).unwrap()).unwrap() } - pub fn write (&mut self, msg: Message) { - msg.write_protocol_string(self.conn()); + pub fn write (&mut self, msg: Message) -> io::IoResult<()> { + try!(msg.write_protocol_string(self.conn())); + Ok(()) } - pub fn run_loop (&mut self, handler: |&mut Client, &Message|) { + pub fn run_loop (&mut self, handler: |&mut Client, &Message| -> io::IoResult<()>) -> io::IoError { loop { let m = self.read(); - handler(self, &m); + match handler(self, &m) { + Err(e) => return e, + _ => {}, + } } } - pub fn run_loop_with_callbacks (mut self, cbs: T) { + pub fn run_loop_with_callbacks (mut self, cbs: T) -> io::IoError { cbs.run_loop(&mut self) } } @@ -162,11 +166,14 @@ pub trait ClientCallbacks { // XXX once storing closures in structs works, we'll also want to provide // a default CallbackClient impl of Client to allow users to not have to // worry about the struct layout for simple cases. - fn run_loop (mut self, client: &mut Client) { - self.on_client_connect(client); + fn run_loop (mut self, client: &mut Client) -> io::IoError { + match self.on_client_connect(client) { + Err(e) => return e, + _ => { }, + } - client.run_loop(|client, m| { - self.on_any_message(client, m); + let err = client.run_loop(|client, m| { + try!(self.on_any_message(client, m)); let from = m.from().as_ref().map(|s| s.as_slice()); let p = m.params().as_slice(); @@ -755,14 +762,17 @@ pub trait ClientCallbacks { }, Reply(_) => { // XXX + Ok(()) }, } }); - self.on_client_disconnect(client); + let _ = self.on_client_disconnect(client); + + err } - fn on_client_connect (&mut self, client: &mut Client) { + fn on_client_connect (&mut self, client: &mut Client) -> io::IoResult<()> { let nick = client.builder().nick.clone(); let pass = client.builder().pass.clone(); let username = client.builder().username.clone(); @@ -771,12 +781,12 @@ pub trait ClientCallbacks { match pass { Some(pass) => { - client.write(Message::new(None, Pass, vec![pass])); + try!(client.write(Message::new(None, Pass, vec![pass]))); }, None => {}, } - client.write(Message::new(None, Nick, vec![nick])); + try!(client.write(Message::new(None, Nick, vec![nick]))); let hostname = match client.builder().hostname { Some(ref host) => host.clone(), @@ -789,64 +799,66 @@ pub trait ClientCallbacks { }, }; - client.write( + try!(client.write( Message::new( None, User, vec![ username, hostname, servername, realname ], ) - ); + )); + + Ok(()) } - #[allow(unused_variable)] fn on_client_disconnect (&mut self, client: &mut Client) { } - - #[allow(unused_variable)] fn on_any_message (&mut self, client: &mut Client, m: &Message) { } - #[allow(unused_variable)] fn on_invalid_message (&mut self, client: &mut Client, m: &Message) { } - #[allow(unused_variable)] fn on_unknown_message (&mut self, client: &mut Client, m: &Message) { } - - #[allow(unused_variable)] fn on_pass (&mut self, client: &mut Client, from: Option<&str>, pass: &str) { } - #[allow(unused_variable)] fn on_nick (&mut self, client: &mut Client, from: Option<&str>, nick: &str, hopcount: Option) { } - #[allow(unused_variable)] fn on_user (&mut self, client: &mut Client, from: Option<&str>, username: &str, hostname: &str, servername: &str, realname: &str) { } - #[allow(unused_variable)] fn on_server (&mut self, client: &mut Client, from: Option<&str>, servername: &str, hopcount: u32, info: &str) { } - #[allow(unused_variable)] fn on_oper (&mut self, client: &mut Client, from: Option<&str>, user: &str, pass: &str) { } - #[allow(unused_variable)] fn on_quit (&mut self, client: &mut Client, from: Option<&str>, msg: Option<&str>) { } - #[allow(unused_variable)] fn on_squit (&mut self, client: &mut Client, from: Option<&str>, server: &str, comment: &str) { } - - #[allow(unused_variable)] fn on_join (&mut self, client: &mut Client, from: Option<&str>, channels: Vec<&str>, keys: Vec<&str>) { } - #[allow(unused_variable)] fn on_part (&mut self, client: &mut Client, from: Option<&str>, channels: Vec<&str>) { } - #[allow(unused_variable)] fn on_channel_mode (&mut self, client: &mut Client, from: Option<&str>, channel: &str, modes: &str, params: Vec<&str>) { } - #[allow(unused_variable)] fn on_user_mode (&mut self, client: &mut Client, from: Option<&str>, nickname: &str, modes: &str) { } - #[allow(unused_variable)] fn on_topic (&mut self, client: &mut Client, from: Option<&str>, channel: &str, topic: Option<&str>) { } - #[allow(unused_variable)] fn on_names (&mut self, client: &mut Client, from: Option<&str>, channels: Vec<&str>) { } - #[allow(unused_variable)] fn on_list (&mut self, client: &mut Client, from: Option<&str>, channels: Vec<&str>, server: Option<&str>) { } - #[allow(unused_variable)] fn on_invite (&mut self, client: &mut Client, from: Option<&str>, nickname: &str, channel: &str) { } - #[allow(unused_variable)] fn on_kick (&mut self, client: &mut Client, from: Option<&str>, channel: &str, user: &str, comment: Option<&str>) { } - - #[allow(unused_variable)] fn on_version (&mut self, client: &mut Client, from: Option<&str>, server: Option<&str>) { } - #[allow(unused_variable)] fn on_stats (&mut self, client: &mut Client, from: Option<&str>, query: Option<&str>, server: Option<&str>) { } - #[allow(unused_variable)] fn on_links (&mut self, client: &mut Client, from: Option<&str>, remote_server: Option<&str>, server_mask: Option<&str>) { } - #[allow(unused_variable)] fn on_time (&mut self, client: &mut Client, from: Option<&str>, server: Option<&str>) { } - #[allow(unused_variable)] fn on_connect (&mut self, client: &mut Client, from: Option<&str>, target_server: &str, port: Option, remote_server: Option<&str>) { } - #[allow(unused_variable)] fn on_trace (&mut self, client: &mut Client, from: Option<&str>, server: Option<&str>) { } - #[allow(unused_variable)] fn on_admin (&mut self, client: &mut Client, from: Option<&str>, server: Option<&str>) { } - #[allow(unused_variable)] fn on_info (&mut self, client: &mut Client, from: Option<&str>, server: Option<&str>) { } - - #[allow(unused_variable)] fn on_privmsg (&mut self, client: &mut Client, from: Option<&str>, receivers: Vec<&str>, text: &str) { } - #[allow(unused_variable)] fn on_notice (&mut self, client: &mut Client, from: Option<&str>, nickname: &str, text: &str) { } - #[allow(unused_variable)] fn on_who (&mut self, client: &mut Client, from: Option<&str>, name: &str, o: bool) { } - #[allow(unused_variable)] fn on_whois (&mut self, client: &mut Client, from: Option<&str>, server: Option<&str>, nickmasks: Vec<&str>) { } - #[allow(unused_variable)] fn on_whowas (&mut self, client: &mut Client, from: Option<&str>, nickname: &str, count: Option, server: Option<&str>) { } - - #[allow(unused_variable)] fn on_kill (&mut self, client: &mut Client, from: Option<&str>, nickname: &str, comment: &str) { } - #[allow(unused_variable)] fn on_ping (&mut self, client: &mut Client, from: Option<&str>, server1: &str, server2: Option<&str>) { } - #[allow(unused_variable)] fn on_pong (&mut self, client: &mut Client, from: Option<&str>, daemon1: &str, daemon2: Option<&str>) { } - #[allow(unused_variable)] fn on_error (&mut self, client: &mut Client, from: Option<&str>, message: &str) { } - - #[allow(unused_variable)] fn on_away (&mut self, client: &mut Client, from: Option<&str>, message: Option<&str>) { } - #[allow(unused_variable)] fn on_rehash (&mut self, client: &mut Client, from: Option<&str>) { } - #[allow(unused_variable)] fn on_restart (&mut self, client: &mut Client, from: Option<&str>) { } - #[allow(unused_variable)] fn on_summon (&mut self, client: &mut Client, from: Option<&str>, user: &str, server: Option<&str>) { } - #[allow(unused_variable)] fn on_users (&mut self, client: &mut Client, from: Option<&str>, server: Option<&str>) { } - #[allow(unused_variable)] fn on_wallops (&mut self, client: &mut Client, from: Option<&str>, text: &str) { } - #[allow(unused_variable)] fn on_userhost (&mut self, client: &mut Client, from: Option<&str>, nicknames: &[&str]) { } - #[allow(unused_variable)] fn on_ison (&mut self, client: &mut Client, from: Option<&str>, nicknames: &[&str]) { } + #[allow(unused_variable)] fn on_client_disconnect (&mut self, client: &mut Client) -> io::IoResult<()> { Ok(()) } + + #[allow(unused_variable)] fn on_any_message (&mut self, client: &mut Client, m: &Message) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_invalid_message (&mut self, client: &mut Client, m: &Message) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_unknown_message (&mut self, client: &mut Client, m: &Message) -> io::IoResult<()> { Ok(()) } + + #[allow(unused_variable)] fn on_pass (&mut self, client: &mut Client, from: Option<&str>, pass: &str) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_nick (&mut self, client: &mut Client, from: Option<&str>, nick: &str, hopcount: Option) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_user (&mut self, client: &mut Client, from: Option<&str>, username: &str, hostname: &str, servername: &str, realname: &str) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_server (&mut self, client: &mut Client, from: Option<&str>, servername: &str, hopcount: u32, info: &str) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_oper (&mut self, client: &mut Client, from: Option<&str>, user: &str, pass: &str) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_quit (&mut self, client: &mut Client, from: Option<&str>, msg: Option<&str>) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_squit (&mut self, client: &mut Client, from: Option<&str>, server: &str, comment: &str) -> io::IoResult<()> { Ok(()) } + + #[allow(unused_variable)] fn on_join (&mut self, client: &mut Client, from: Option<&str>, channels: Vec<&str>, keys: Vec<&str>) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_part (&mut self, client: &mut Client, from: Option<&str>, channels: Vec<&str>) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_channel_mode (&mut self, client: &mut Client, from: Option<&str>, channel: &str, modes: &str, params: Vec<&str>) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_user_mode (&mut self, client: &mut Client, from: Option<&str>, nickname: &str, modes: &str) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_topic (&mut self, client: &mut Client, from: Option<&str>, channel: &str, topic: Option<&str>) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_names (&mut self, client: &mut Client, from: Option<&str>, channels: Vec<&str>) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_list (&mut self, client: &mut Client, from: Option<&str>, channels: Vec<&str>, server: Option<&str>) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_invite (&mut self, client: &mut Client, from: Option<&str>, nickname: &str, channel: &str) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_kick (&mut self, client: &mut Client, from: Option<&str>, channel: &str, user: &str, comment: Option<&str>) -> io::IoResult<()> { Ok(()) } + + #[allow(unused_variable)] fn on_version (&mut self, client: &mut Client, from: Option<&str>, server: Option<&str>) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_stats (&mut self, client: &mut Client, from: Option<&str>, query: Option<&str>, server: Option<&str>) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_links (&mut self, client: &mut Client, from: Option<&str>, remote_server: Option<&str>, server_mask: Option<&str>) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_time (&mut self, client: &mut Client, from: Option<&str>, server: Option<&str>) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_connect (&mut self, client: &mut Client, from: Option<&str>, target_server: &str, port: Option, remote_server: Option<&str>) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_trace (&mut self, client: &mut Client, from: Option<&str>, server: Option<&str>) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_admin (&mut self, client: &mut Client, from: Option<&str>, server: Option<&str>) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_info (&mut self, client: &mut Client, from: Option<&str>, server: Option<&str>) -> io::IoResult<()> { Ok(()) } + + #[allow(unused_variable)] fn on_privmsg (&mut self, client: &mut Client, from: Option<&str>, receivers: Vec<&str>, text: &str) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_notice (&mut self, client: &mut Client, from: Option<&str>, nickname: &str, text: &str) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_who (&mut self, client: &mut Client, from: Option<&str>, name: &str, o: bool) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_whois (&mut self, client: &mut Client, from: Option<&str>, server: Option<&str>, nickmasks: Vec<&str>) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_whowas (&mut self, client: &mut Client, from: Option<&str>, nickname: &str, count: Option, server: Option<&str>) -> io::IoResult<()> { Ok(()) } + + #[allow(unused_variable)] fn on_kill (&mut self, client: &mut Client, from: Option<&str>, nickname: &str, comment: &str) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_ping (&mut self, client: &mut Client, from: Option<&str>, server1: &str, server2: Option<&str>) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_pong (&mut self, client: &mut Client, from: Option<&str>, daemon1: &str, daemon2: Option<&str>) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_error (&mut self, client: &mut Client, from: Option<&str>, message: &str) -> io::IoResult<()> { Ok(()) } + + #[allow(unused_variable)] fn on_away (&mut self, client: &mut Client, from: Option<&str>, message: Option<&str>) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_rehash (&mut self, client: &mut Client, from: Option<&str>) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_restart (&mut self, client: &mut Client, from: Option<&str>) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_summon (&mut self, client: &mut Client, from: Option<&str>, user: &str, server: Option<&str>) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_users (&mut self, client: &mut Client, from: Option<&str>, server: Option<&str>) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_wallops (&mut self, client: &mut Client, from: Option<&str>, text: &str) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_userhost (&mut self, client: &mut Client, from: Option<&str>, nicknames: &[&str]) -> io::IoResult<()> { Ok(()) } + #[allow(unused_variable)] fn on_ison (&mut self, client: &mut Client, from: Option<&str>, nicknames: &[&str]) -> io::IoResult<()> { Ok(()) } } fn is_channel (name: &str) -> bool { diff --git a/src/message.rs b/src/message.rs index b90cafb..b7076d5 100644 --- a/src/message.rs +++ b/src/message.rs @@ -45,30 +45,33 @@ impl Message { &self.params } - pub fn write_protocol_string (&self, w: &mut W) { + pub fn write_protocol_string (&self, w: &mut W) -> io::IoResult<()> { match self.from { - Some(ref f) => { write!(w, ":{} ", f); }, + Some(ref f) => { try!(write!(w, ":{} ", f)) }, None => {}, } - write!(w, "{}", self.message_type); + try!(write!(w, "{}", self.message_type)); for param in self.params.iter() { if param.as_slice().contains_char(' ') { - write!(w, " :{}", param); + try!(write!(w, " :{}", param)); } else { - write!(w, " {}", param); + try!(write!(w, " {}", param)); } } - write!(w, "\r\n"); - w.flush(); + try!(write!(w, "\r\n")); + try!(w.flush()); + + Ok(()) } pub fn to_protocol_string (&self) -> String { let mut w = io::MemWriter::new(); - self.write_protocol_string(&mut w); + // this should never fail, so unwrap is fine + self.write_protocol_string(&mut w).unwrap(); // XXX error handling, encoding String::from_utf8(w.unwrap()).unwrap() } -- cgit v1.2.3