From 6c826625fd0af7039ddd85b85dd9ed3923262ff6 Mon Sep 17 00:00:00 2001 From: Matt McCoy Date: Thu, 23 Jun 2016 22:44:12 -0400 Subject: [PATCH] Initial work for adding errors --- src/client.rs | 12 ++++++----- src/error.rs | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + src/parse.rs | 7 +++--- 4 files changed, 72 insertions(+), 8 deletions(-) create mode 100644 src/error.rs diff --git a/src/client.rs b/src/client.rs index 51f85ab..7bd8107 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,9 +1,11 @@ use std::net::{TcpStream, ToSocketAddrs}; use openssl::ssl::{SslContext, SslStream}; -use std::io::{Error, ErrorKind, Read, Result, Write}; +use std::io::{ErrorKind, Read, Write}; +use std::io::{self}; use super::mailbox::Mailbox; use super::parse::{parse_response_ok, parse_capability, parse_select_or_examine}; +use super::error::{Error, Result}; static TAG_PREFIX: &'static str = "a"; const INITIAL_TAG: u32 = 0; @@ -27,7 +29,7 @@ impl Client { try!(socket.read_greeting()); Ok(socket) }, - Err(e) => Err(e) + Err(e) => Err(Error::Io(e)) } } } @@ -45,7 +47,7 @@ impl Client> { try!(socket.read_greeting()); Ok(socket) }, - Err(e) => Err(e) + Err(e) => Err(Error::Io(e)) } } } @@ -159,7 +161,7 @@ impl Client { match self.stream.write_fmt(format_args!("{}", &*command)) { Ok(_) => (), - Err(_) => return Err(Error::new(ErrorKind::Other, "Failed to write")), + Err(_) => return Err(Error::Io(io::Error::new(io::ErrorKind::Other, "Failed to write"))), }; self.read_response() @@ -204,7 +206,7 @@ impl Client { let byte_buffer: &mut [u8] = &mut [0]; match self.stream.read(byte_buffer) { Ok(_) => {}, - Err(_) => return Err(Error::new(ErrorKind::Other, "Failed to read line")), + Err(_) => return Err(Error::Io(io::Error::new(io::ErrorKind::Other, "Failed to read line"))), } line_buffer.push(byte_buffer[0]); } diff --git a/src/error.rs b/src/error.rs new file mode 100644 index 0000000..8084b46 --- /dev/null +++ b/src/error.rs @@ -0,0 +1,60 @@ +extern crate openssl; + +use std::io::{self}; +use std::result; +use std::fmt::{self}; +use std::error::Error as StdError; + +use openssl::ssl::error::SslError; + +pub type Result = result::Result; + +/// A set of errors that can occur in the IMAP client +#[derive(Debug)] +pub enum Error { + Io(io::Error), + Ssl(SslError), + BadResponse(Vec), + NoResponse(Vec), +} + +impl From for Error { + fn from(err: io::Error) -> Error { + Error::Io(err) + } +} + +impl From for Error { + fn from(err: SslError) -> Error { + Error::Ssl(err) + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Error::Io(ref e) => fmt::Display::fmt(e, f), + Error::Ssl(ref e) => fmt::Display::fmt(e, f), + ref e => f.write_str(e.description()), + } + } +} + +impl StdError for Error { + fn description(&self) -> &str { + match *self { + Error::Io(ref e) => e.description(), + Error::Ssl(ref e) => e.description(), + Error::BadResponse(_) => "Bad Response", + Error::NoResponse(_) => "No Response" + } + } + + fn cause(&self) -> Option<&StdError> { + match *self { + Error::Io(ref e) => Some(e), + Error::Ssl(ref e) => Some(e), + _ => None, + } + } +} diff --git a/src/lib.rs b/src/lib.rs index b0afb0b..affa530 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,6 +7,7 @@ extern crate openssl; extern crate regex; pub mod client; +pub mod error; pub mod mailbox; mod parse; diff --git a/src/parse.rs b/src/parse.rs index 0fbbbef..d8b522f 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -1,7 +1,8 @@ -use std::io::{Error, ErrorKind, Result}; +use std::io::{self}; use regex::Regex; use super::mailbox::Mailbox; +use super::error::{Error, Result}; pub fn parse_capability(lines: Vec) -> Result> { let capability_regex = Regex::new(r"^\* CAPABILITY (.*)\r\n").unwrap(); @@ -20,7 +21,7 @@ pub fn parse_capability(lines: Vec) -> Result> { } } - Err(Error::new(ErrorKind::Other, "Error parsing capabilities response")) + Err(Error::Io(io::Error::new(io::ErrorKind::Other, "Error parsing capabilities response"))) } pub fn parse_response_ok(lines: Vec) -> Result<()> { @@ -34,7 +35,7 @@ pub fn parse_response_ok(lines: Vec) -> Result<()> { } } - return Err(Error::new(ErrorKind::Other, format!("Invalid Response: {}", last_line).to_string())); + Err(Error::Io(io::Error::new(io::ErrorKind::Other, format!("Invalid Response: {}", last_line).to_string()))) } pub fn parse_select_or_examine(lines: Vec) -> Result {