Use try! macro instead of explicity match Results
This commit is contained in:
parent
ed03acf07d
commit
be8796fe49
1 changed files with 59 additions and 87 deletions
146
src/client.rs
146
src/client.rs
|
|
@ -33,14 +33,10 @@ impl Client<TcpStream> {
|
||||||
/// This will upgrade a regular TCP connection to use SSL.
|
/// This will upgrade a regular TCP connection to use SSL.
|
||||||
pub fn secure(mut self, ssl_context: SslContext) -> Result<Client<SslStream<TcpStream>>> {
|
pub fn secure(mut self, ssl_context: SslContext) -> Result<Client<SslStream<TcpStream>>> {
|
||||||
// TODO This needs to be tested
|
// TODO This needs to be tested
|
||||||
match self.run_command_and_check_ok("STARTTLS") {
|
try!(self.run_command_and_check_ok("STARTTLS"));
|
||||||
Err(e) => return Err(e),
|
SslStream::connect(&ssl_context, self.stream)
|
||||||
_ => {}
|
.map(|s| Client::new(s))
|
||||||
};
|
.map_err(|e| Error::Ssl(e))
|
||||||
match SslStream::connect(&ssl_context, self.stream) {
|
|
||||||
Ok(s) => Ok(Client::new(s)),
|
|
||||||
Err(e) => Err(Error::Ssl(e))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -75,49 +71,37 @@ impl<T: Read+Write> Client<T> {
|
||||||
|
|
||||||
/// Authenticate will authenticate with the server, using the authenticator given.
|
/// Authenticate will authenticate with the server, using the authenticator given.
|
||||||
pub fn authenticate<A: Authenticator>(&mut self, auth_type: &str, authenticator: A) -> Result<()> {
|
pub fn authenticate<A: Authenticator>(&mut self, auth_type: &str, authenticator: A) -> Result<()> {
|
||||||
match self.run_command(&format!("AUTHENTICATE {}", auth_type).to_string()) {
|
try!(self.run_command(&format!("AUTHENTICATE {}", auth_type).to_string()));
|
||||||
Ok(_) => self.do_auth_handshake(authenticator),
|
self.do_auth_handshake(authenticator)
|
||||||
Err(e) => Err(e)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This func does the handshake process once the authenticate command is made.
|
/// This func does the handshake process once the authenticate command is made.
|
||||||
fn do_auth_handshake<A: Authenticator>(&mut self, authenticator: A) -> Result<()> {
|
fn do_auth_handshake<A: Authenticator>(&mut self, authenticator: A) -> Result<()> {
|
||||||
// TODO Clean up this code
|
// TODO Clean up this code
|
||||||
loop {
|
loop {
|
||||||
let line = match self.readline() {
|
let line = try!(self.readline());
|
||||||
Ok(l) => l,
|
|
||||||
Err(e) => return Err(e)
|
|
||||||
};
|
|
||||||
if line.starts_with(b"+") {
|
if line.starts_with(b"+") {
|
||||||
let data = match parse_authenticate_response(String::from_utf8(line).unwrap()) {
|
let data = try!(parse_authenticate_response(String::from_utf8(line).unwrap()));
|
||||||
Ok(d) => d,
|
|
||||||
Err(e) => return Err(e)
|
|
||||||
};
|
|
||||||
let auth_response = authenticator.process(data);
|
let auth_response = authenticator.process(data);
|
||||||
match self.stream.write_all(auth_response.into_bytes().as_slice()) {
|
|
||||||
Err(e) => return Err(Error::Io(e)),
|
if let Err(e) = self.stream.write_all(auth_response.into_bytes().as_slice()) {
|
||||||
_ => {}
|
return Err(Error::Io(e));
|
||||||
};
|
}
|
||||||
match self.stream.write(vec![0x0d, 0x0a].as_slice()) {
|
|
||||||
Err(e) => return Err(Error::Io(e)),
|
if let Err(e) = self.stream.write(vec![0x0d, 0x0a].as_slice()) {
|
||||||
_ => {}
|
return Err(Error::Io(e));
|
||||||
};
|
}
|
||||||
|
|
||||||
} else if line.starts_with(format!("{}{} ", TAG_PREFIX, self.tag).as_bytes()) {
|
} else if line.starts_with(format!("{}{} ", TAG_PREFIX, self.tag).as_bytes()) {
|
||||||
match parse_response(vec![String::from_utf8(line).unwrap()]) {
|
try!(parse_response(vec![String::from_utf8(line).unwrap()]));
|
||||||
Ok(_) => return Ok(()),
|
return Ok(());
|
||||||
Err(e) => return Err(e)
|
|
||||||
};
|
|
||||||
} else {
|
} else {
|
||||||
let mut lines = match self.read_response() {
|
let mut lines = try!(self.read_response());
|
||||||
Ok(l) => l,
|
|
||||||
Err(e) => return Err(e)
|
|
||||||
};
|
|
||||||
lines.insert(0, String::from_utf8(line).unwrap());
|
lines.insert(0, String::from_utf8(line).unwrap());
|
||||||
match parse_response(lines.clone()) {
|
try!(parse_response(lines.clone()));
|
||||||
Ok(_) => return Ok(()),
|
return Ok(());
|
||||||
Err(e) => return Err(e)
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -129,18 +113,18 @@ impl<T: Read+Write> Client<T> {
|
||||||
|
|
||||||
/// Selects a mailbox
|
/// Selects a mailbox
|
||||||
pub fn select(&mut self, mailbox_name: &str) -> Result<Mailbox> {
|
pub fn select(&mut self, mailbox_name: &str) -> Result<Mailbox> {
|
||||||
match self.run_command_and_read_response(&format!("SELECT {}", mailbox_name).to_string()) {
|
let lines = try!(
|
||||||
Ok(lines) => parse_select_or_examine(lines),
|
self.run_command_and_read_response(&format!("SELECT {}", mailbox_name).to_string())
|
||||||
Err(e) => Err(e)
|
);
|
||||||
}
|
parse_select_or_examine(lines)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Examine is identical to Select, but the selected mailbox is identified as read-only
|
/// Examine is identical to Select, but the selected mailbox is identified as read-only
|
||||||
pub fn examine(&mut self, mailbox_name: &str) -> Result<Mailbox> {
|
pub fn examine(&mut self, mailbox_name: &str) -> Result<Mailbox> {
|
||||||
match self.run_command_and_read_response(&format!("EXAMINE {}", mailbox_name).to_string()) {
|
let lines = try!(
|
||||||
Ok(lines) => parse_select_or_examine(lines),
|
self.run_command_and_read_response(&format!("EXAMINE {}", mailbox_name).to_string())
|
||||||
Err(e) => Err(e)
|
);
|
||||||
}
|
parse_select_or_examine(lines)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fetch retreives data associated with a message in the mailbox.
|
/// Fetch retreives data associated with a message in the mailbox.
|
||||||
|
|
@ -187,10 +171,10 @@ impl<T: Read+Write> Client<T> {
|
||||||
|
|
||||||
/// Capability requests a listing of capabilities that the server supports.
|
/// Capability requests a listing of capabilities that the server supports.
|
||||||
pub fn capability(&mut self) -> Result<Vec<String>> {
|
pub fn capability(&mut self) -> Result<Vec<String>> {
|
||||||
match self.run_command_and_read_response(&format!("CAPABILITY").to_string()) {
|
let lines = try!(
|
||||||
Ok(lines) => parse_capability(lines),
|
self.run_command_and_read_response(&format!("CAPABILITY").to_string())
|
||||||
Err(e) => Err(e)
|
);
|
||||||
}
|
parse_capability(lines)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Expunge permanently removes all messages that have the \Deleted flag set from the currently
|
/// Expunge permanently removes all messages that have the \Deleted flag set from the currently
|
||||||
|
|
@ -234,35 +218,30 @@ impl<T: Read+Write> Client<T> {
|
||||||
|
|
||||||
/// Runs a command and checks if it returns OK.
|
/// Runs a command and checks if it returns OK.
|
||||||
pub fn run_command_and_check_ok(&mut self, command: &str) -> Result<()> {
|
pub fn run_command_and_check_ok(&mut self, command: &str) -> Result<()> {
|
||||||
match self.run_command_and_read_response(command) {
|
let lines = try!(self.run_command_and_read_response(command));
|
||||||
Ok(lines) => parse_response_ok(lines),
|
parse_response_ok(lines)
|
||||||
Err(e) => Err(e)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run a command and parse the status response.
|
// Run a command and parse the status response.
|
||||||
pub fn run_command_and_parse(&mut self, command: &str) -> Result<Vec<String>> {
|
pub fn run_command_and_parse(&mut self, command: &str) -> Result<Vec<String>> {
|
||||||
match self.run_command_and_read_response(command) {
|
let lines = try!(self.run_command_and_read_response(command));
|
||||||
Ok(lines) => parse_response(lines),
|
parse_response(lines)
|
||||||
Err(e) => Err(e)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Runs any command passed to it.
|
/// Runs any command passed to it.
|
||||||
pub fn run_command(&mut self, untagged_command: &str) -> Result<()> {
|
pub fn run_command(&mut self, untagged_command: &str) -> Result<()> {
|
||||||
let command = self.create_command(untagged_command.to_string());
|
let command = self.create_command(untagged_command.to_string());
|
||||||
|
|
||||||
match self.stream.write_fmt(format_args!("{}", &*command)) {
|
if let Err(_) = self.stream.write_fmt(format_args!("{}", &*command)) {
|
||||||
Ok(_) => Ok(()),
|
return Err(Error::Io(io::Error::new(io::ErrorKind::Other, "Failed to write")));
|
||||||
Err(_) => Err(Error::Io(io::Error::new(io::ErrorKind::Other, "Failed to write"))),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_command_and_read_response(&mut self, untagged_command: &str) -> Result<Vec<String>> {
|
pub fn run_command_and_read_response(&mut self, untagged_command: &str) -> Result<Vec<String>> {
|
||||||
match self.run_command(untagged_command) {
|
try!(self.run_command(untagged_command));
|
||||||
Ok(_) => self.read_response(),
|
self.read_response()
|
||||||
Err(e) => Err(e)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_response(&mut self) -> Result<Vec<String>> {
|
fn read_response(&mut self) -> Result<Vec<String>> {
|
||||||
|
|
@ -271,15 +250,11 @@ impl<T: Read+Write> Client<T> {
|
||||||
let mut lines: Vec<String> = Vec::new();
|
let mut lines: Vec<String> = Vec::new();
|
||||||
|
|
||||||
while !found_tag_line {
|
while !found_tag_line {
|
||||||
match self.readline() {
|
let raw_data = try!(self.readline());
|
||||||
Ok(raw_data) => {
|
let line = String::from_utf8(raw_data).unwrap();
|
||||||
let line = String::from_utf8(raw_data).unwrap();
|
lines.push(line.clone());
|
||||||
lines.push(line.clone());
|
if (&*line).starts_with(&*start_str) {
|
||||||
if (&*line).starts_with(&*start_str) {
|
found_tag_line = true;
|
||||||
found_tag_line = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Err(err) => return Err(err)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -287,10 +262,8 @@ impl<T: Read+Write> Client<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_greeting(&mut self) -> Result<()> {
|
fn read_greeting(&mut self) -> Result<()> {
|
||||||
match self.readline() {
|
try!(self.readline());
|
||||||
Ok(_) => Ok(()),
|
Ok(())
|
||||||
Err(err) => Err(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn readline(&mut self) -> Result<Vec<u8>> {
|
fn readline(&mut self) -> Result<Vec<u8>> {
|
||||||
|
|
@ -301,13 +274,12 @@ impl<T: Read+Write> Client<T> {
|
||||||
|
|
||||||
let mut line_buffer: Vec<u8> = Vec::new();
|
let mut line_buffer: Vec<u8> = Vec::new();
|
||||||
while line_buffer.len() < 2 || (line_buffer[line_buffer.len()-1] != lf && line_buffer[line_buffer.len()-2] != cr) {
|
while line_buffer.len() < 2 || (line_buffer[line_buffer.len()-1] != lf && line_buffer[line_buffer.len()-2] != cr) {
|
||||||
let byte_buffer: &mut [u8] = &mut [0];
|
let byte_buffer: &mut [u8] = &mut [0];
|
||||||
match self.stream.read(byte_buffer) {
|
if let Err(_) = self.stream.read(byte_buffer) {
|
||||||
Ok(_) => {},
|
return Err(Error::Io(io::Error::new(io::ErrorKind::Other, "Failed to read line")));
|
||||||
Err(_) => return Err(Error::Io(io::Error::new(io::ErrorKind::Other, "Failed to read line"))),
|
}
|
||||||
}
|
print!("{}", String::from_utf8_lossy(byte_buffer));
|
||||||
print!("{}", String::from_utf8_lossy(byte_buffer));
|
line_buffer.push(byte_buffer[0]);
|
||||||
line_buffer.push(byte_buffer[0]);
|
|
||||||
}
|
}
|
||||||
Ok(line_buffer)
|
Ok(line_buffer)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue