Initial work for adding errors

This commit is contained in:
Matt McCoy 2016-06-23 22:44:12 -04:00
parent 923339e5f0
commit 6c826625fd
4 changed files with 72 additions and 8 deletions

View file

@ -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<TcpStream> {
try!(socket.read_greeting());
Ok(socket)
},
Err(e) => Err(e)
Err(e) => Err(Error::Io(e))
}
}
}
@ -45,7 +47,7 @@ impl Client<SslStream<TcpStream>> {
try!(socket.read_greeting());
Ok(socket)
},
Err(e) => Err(e)
Err(e) => Err(Error::Io(e))
}
}
}
@ -159,7 +161,7 @@ impl<T: Read+Write> Client<T> {
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<T: Read+Write> Client<T> {
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]);
}

60
src/error.rs Normal file
View file

@ -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<T> = result::Result<T, Error>;
/// A set of errors that can occur in the IMAP client
#[derive(Debug)]
pub enum Error {
Io(io::Error),
Ssl(SslError),
BadResponse(Vec<String>),
NoResponse(Vec<String>),
}
impl From<io::Error> for Error {
fn from(err: io::Error) -> Error {
Error::Io(err)
}
}
impl From<SslError> 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,
}
}
}

View file

@ -7,6 +7,7 @@ extern crate openssl;
extern crate regex;
pub mod client;
pub mod error;
pub mod mailbox;
mod parse;

View file

@ -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<String>) -> Result<Vec<String>> {
let capability_regex = Regex::new(r"^\* CAPABILITY (.*)\r\n").unwrap();
@ -20,7 +21,7 @@ pub fn parse_capability(lines: Vec<String>) -> Result<Vec<String>> {
}
}
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<String>) -> Result<()> {
@ -34,7 +35,7 @@ pub fn parse_response_ok(lines: Vec<String>) -> 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<String>) -> Result<Mailbox> {