rustfmt the codebase (#36)
This will ensure that we are properly formatting this library code according to rust standards
This commit is contained in:
parent
62cef4a773
commit
86e1d46507
8 changed files with 802 additions and 651 deletions
54
README.md
54
README.md
|
|
@ -22,36 +22,40 @@ use imap::client::Client;
|
|||
// See: https://support.google.com/accounts/answer/6010255?hl=en
|
||||
// Look at the gmail_oauth2.rs example on how to connect to a gmail server securely.
|
||||
fn main() {
|
||||
let mut imap_socket = Client::secure_connect(("imap.gmail.com", 993), "imap.gmail.com", SslConnectorBuilder::new(SslMethod::tls()).unwrap().build()).unwrap();
|
||||
let domain = "imap.gmail.com";
|
||||
let port = 993;
|
||||
let socket_addr = (domain, port);
|
||||
let ssl_connector = SslConnectorBuilder::new(SslMethod::tls()).unwrap().build();
|
||||
let mut imap_socket = Client::secure_connect(socket_addr, domain, ssl_connector).unwrap();
|
||||
|
||||
imap_socket.login("username", "password").unwrap();
|
||||
imap_socket.login("username", "password").unwrap();
|
||||
|
||||
match imap_socket.capability() {
|
||||
Ok(capabilities) => {
|
||||
for capability in capabilities.iter() {
|
||||
println!("{}", capability);
|
||||
}
|
||||
},
|
||||
Err(e) => println!("Error parsing capability: {}", e)
|
||||
};
|
||||
match imap_socket.capability() {
|
||||
Ok(capabilities) => {
|
||||
for capability in capabilities.iter() {
|
||||
println!("{}", capability);
|
||||
}
|
||||
}
|
||||
Err(e) => println!("Error parsing capability: {}", e),
|
||||
};
|
||||
|
||||
match imap_socket.select("INBOX") {
|
||||
Ok(mailbox) => {
|
||||
println!("{}", mailbox);
|
||||
},
|
||||
Err(e) => println!("Error selecting INBOX: {}", e)
|
||||
};
|
||||
match imap_socket.select("INBOX") {
|
||||
Ok(mailbox) => {
|
||||
println!("{}", mailbox);
|
||||
}
|
||||
Err(e) => println!("Error selecting INBOX: {}", e),
|
||||
};
|
||||
|
||||
match imap_socket.fetch("2", "body[text]") {
|
||||
Ok(lines) => {
|
||||
for line in lines.iter() {
|
||||
print!("{}", line);
|
||||
}
|
||||
},
|
||||
Err(e) => println!("Error Fetching email 2: {}", e)
|
||||
};
|
||||
match imap_socket.fetch("2", "body[text]") {
|
||||
Ok(lines) => {
|
||||
for line in lines.iter() {
|
||||
print!("{}", line);
|
||||
}
|
||||
}
|
||||
Err(e) => println!("Error Fetching email 2: {}", e),
|
||||
};
|
||||
|
||||
imap_socket.logout().unwrap();
|
||||
imap_socket.logout().unwrap();
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -8,34 +8,38 @@ use imap::client::Client;
|
|||
// See: https://support.google.com/accounts/answer/6010255?hl=en
|
||||
// Look at the gmail_oauth2.rs example on how to connect to a gmail server securely.
|
||||
fn main() {
|
||||
let mut imap_socket = Client::secure_connect(("imap.gmail.com", 993), "imap.gmail.com", SslConnectorBuilder::new(SslMethod::tls()).unwrap().build()).unwrap();
|
||||
let domain = "imap.gmail.com";
|
||||
let port = 993;
|
||||
let socket_addr = (domain, port);
|
||||
let ssl_connector = SslConnectorBuilder::new(SslMethod::tls()).unwrap().build();
|
||||
let mut imap_socket = Client::secure_connect(socket_addr, domain, ssl_connector).unwrap();
|
||||
|
||||
imap_socket.login("username", "password").unwrap();
|
||||
imap_socket.login("username", "password").unwrap();
|
||||
|
||||
match imap_socket.capability() {
|
||||
Ok(capabilities) => {
|
||||
for capability in capabilities.iter() {
|
||||
println!("{}", capability);
|
||||
}
|
||||
},
|
||||
Err(e) => println!("Error parsing capability: {}", e)
|
||||
};
|
||||
match imap_socket.capability() {
|
||||
Ok(capabilities) => {
|
||||
for capability in capabilities.iter() {
|
||||
println!("{}", capability);
|
||||
}
|
||||
}
|
||||
Err(e) => println!("Error parsing capability: {}", e),
|
||||
};
|
||||
|
||||
match imap_socket.select("INBOX") {
|
||||
Ok(mailbox) => {
|
||||
println!("{}", mailbox);
|
||||
},
|
||||
Err(e) => println!("Error selecting INBOX: {}", e)
|
||||
};
|
||||
match imap_socket.select("INBOX") {
|
||||
Ok(mailbox) => {
|
||||
println!("{}", mailbox);
|
||||
}
|
||||
Err(e) => println!("Error selecting INBOX: {}", e),
|
||||
};
|
||||
|
||||
match imap_socket.fetch("2", "body[text]") {
|
||||
Ok(lines) => {
|
||||
for line in lines.iter() {
|
||||
print!("{}", line);
|
||||
}
|
||||
},
|
||||
Err(e) => println!("Error Fetching email 2: {}", e)
|
||||
};
|
||||
match imap_socket.fetch("2", "body[text]") {
|
||||
Ok(lines) => {
|
||||
for line in lines.iter() {
|
||||
print!("{}", line);
|
||||
}
|
||||
}
|
||||
Err(e) => println!("Error Fetching email 2: {}", e),
|
||||
};
|
||||
|
||||
imap_socket.logout().unwrap();
|
||||
imap_socket.logout().unwrap();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,34 +3,44 @@ extern crate openssl;
|
|||
extern crate base64;
|
||||
|
||||
use openssl::ssl::{SslConnectorBuilder, SslMethod};
|
||||
use base64::{encode};
|
||||
use base64::encode;
|
||||
use imap::client::Client;
|
||||
use imap::authenticator::Authenticator;
|
||||
|
||||
struct GmailOAuth2 {
|
||||
user: String,
|
||||
access_token: String
|
||||
access_token: String,
|
||||
}
|
||||
|
||||
impl Authenticator for GmailOAuth2 {
|
||||
#[allow(unused_variables)]
|
||||
fn process(&self, data: String) -> String {
|
||||
encode(format!("user={}\x01auth=Bearer {}\x01\x01", self.user, self.access_token).as_bytes())
|
||||
encode(
|
||||
format!(
|
||||
"user={}\x01auth=Bearer {}\x01\x01",
|
||||
self.user,
|
||||
self.access_token
|
||||
).as_bytes(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let gmail_auth = GmailOAuth2{
|
||||
let gmail_auth = GmailOAuth2 {
|
||||
user: String::from("sombody@gmail.com"),
|
||||
access_token: String::from("<access_token>")
|
||||
access_token: String::from("<access_token>"),
|
||||
};
|
||||
let mut imap_socket = Client::secure_connect(("imap.gmail.com", 993), "imap.gmail.com", SslConnectorBuilder::new(SslMethod::tls()).unwrap().build()).unwrap();
|
||||
let domain = "imap.gmail.com";
|
||||
let port = 993;
|
||||
let socket_addr = (domain, port);
|
||||
let ssl_connector = SslConnectorBuilder::new(SslMethod::tls()).unwrap().build();
|
||||
let mut imap_socket = Client::secure_connect(socket_addr, domain, ssl_connector).unwrap();
|
||||
|
||||
imap_socket.authenticate("XOAUTH2", gmail_auth).unwrap();
|
||||
|
||||
match imap_socket.select("INBOX") {
|
||||
Ok(mailbox) => println!("{}", mailbox),
|
||||
Err(e) => println!("Error selecting INBOX: {}", e)
|
||||
Err(e) => println!("Error selecting INBOX: {}", e),
|
||||
};
|
||||
|
||||
match imap_socket.fetch("2", "body[text]") {
|
||||
|
|
@ -38,8 +48,8 @@ fn main() {
|
|||
for line in lines.iter() {
|
||||
print!("{}", line);
|
||||
}
|
||||
},
|
||||
Err(e) => println!("Error Fetching email 2: {}", e)
|
||||
}
|
||||
Err(e) => println!("Error Fetching email 2: {}", e),
|
||||
};
|
||||
|
||||
imap_socket.logout().unwrap();
|
||||
|
|
|
|||
1188
src/client.rs
1188
src/client.rs
File diff suppressed because it is too large
Load diff
10
src/error.rs
10
src/error.rs
|
|
@ -22,7 +22,7 @@ pub enum Error {
|
|||
// Error parsing a server response.
|
||||
Parse(ParseError),
|
||||
// Error appending a mail
|
||||
Append
|
||||
Append,
|
||||
}
|
||||
|
||||
impl From<IoError> for Error {
|
||||
|
|
@ -55,7 +55,7 @@ impl StdError for Error {
|
|||
Error::Parse(ref e) => e.description(),
|
||||
Error::BadResponse(_) => "Bad Response",
|
||||
Error::NoResponse(_) => "No Response",
|
||||
Error::Append => "Could not append mail to mailbox"
|
||||
Error::Append => "Could not append mail to mailbox",
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -75,7 +75,7 @@ pub enum ParseError {
|
|||
// Error parsing the cabability response.
|
||||
Capability(Vec<String>),
|
||||
// Authentication errors.
|
||||
Authentication(String)
|
||||
Authentication(String),
|
||||
}
|
||||
|
||||
impl fmt::Display for ParseError {
|
||||
|
|
@ -91,13 +91,13 @@ impl StdError for ParseError {
|
|||
match *self {
|
||||
ParseError::StatusResponse(_) => "Unable to parse status response",
|
||||
ParseError::Capability(_) => "Unable to parse capability response",
|
||||
ParseError::Authentication(_) => "Unable to parse authentication response"
|
||||
ParseError::Authentication(_) => "Unable to parse authentication response",
|
||||
}
|
||||
}
|
||||
|
||||
fn cause(&self) -> Option<&StdError> {
|
||||
match *self {
|
||||
_ => None
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,32 +1,43 @@
|
|||
use std::fmt;
|
||||
|
||||
#[derive(Eq,PartialEq)]
|
||||
#[derive(Eq, PartialEq)]
|
||||
pub struct Mailbox {
|
||||
pub flags: String,
|
||||
pub exists: u32,
|
||||
pub recent: u32,
|
||||
pub unseen: Option<u32>,
|
||||
pub permanent_flags: Option<String>,
|
||||
pub uid_next: Option<u32>,
|
||||
pub uid_validity: Option<u32>
|
||||
pub flags: String,
|
||||
pub exists: u32,
|
||||
pub recent: u32,
|
||||
pub unseen: Option<u32>,
|
||||
pub permanent_flags: Option<String>,
|
||||
pub uid_next: Option<u32>,
|
||||
pub uid_validity: Option<u32>,
|
||||
}
|
||||
|
||||
impl Default for Mailbox {
|
||||
fn default() -> Mailbox {
|
||||
Mailbox {
|
||||
flags: "".to_string(),
|
||||
exists: 0,
|
||||
recent: 0,
|
||||
unseen: None,
|
||||
permanent_flags: None,
|
||||
uid_next: None,
|
||||
uid_validity: None
|
||||
}
|
||||
}
|
||||
fn default() -> Mailbox {
|
||||
Mailbox {
|
||||
flags: "".to_string(),
|
||||
exists: 0,
|
||||
recent: 0,
|
||||
unseen: None,
|
||||
permanent_flags: None,
|
||||
uid_next: None,
|
||||
uid_validity: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Mailbox {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "flags: {}, exists: {}, recent: {}, unseen: {:?}, permanent_flags: {:?}, uid_next: {:?}, uid_validity: {:?}", self.flags, self.exists, self.recent, self.unseen, self.permanent_flags, self.uid_next, self.uid_validity)
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"flags: {}, exists: {}, recent: {}, unseen: {:?}, permanent_flags: {:?},\
|
||||
uid_next: {:?}, uid_validity: {:?}",
|
||||
self.flags,
|
||||
self.exists,
|
||||
self.recent,
|
||||
self.unseen,
|
||||
self.permanent_flags,
|
||||
self.uid_next,
|
||||
self.uid_validity
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,32 +6,32 @@ pub struct MockStream {
|
|||
read_pos: usize,
|
||||
pub written_buf: Vec<u8>,
|
||||
err_on_read: bool,
|
||||
read_delay: usize
|
||||
read_delay: usize,
|
||||
}
|
||||
|
||||
impl MockStream {
|
||||
pub fn new(read_buf: Vec<u8>) -> MockStream {
|
||||
MockStream{
|
||||
MockStream {
|
||||
read_buf: read_buf,
|
||||
read_pos: 0,
|
||||
written_buf: Vec::new(),
|
||||
err_on_read: false,
|
||||
read_delay: 0
|
||||
read_delay: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_err() -> MockStream {
|
||||
MockStream{
|
||||
MockStream {
|
||||
read_buf: Vec::new(),
|
||||
read_pos: 0,
|
||||
written_buf: Vec::new(),
|
||||
err_on_read: true,
|
||||
read_delay: 0
|
||||
read_delay: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_read_delay(read_buf: Vec<u8>) -> MockStream {
|
||||
MockStream{
|
||||
MockStream {
|
||||
read_buf: read_buf,
|
||||
read_pos: 0,
|
||||
written_buf: Vec::new(),
|
||||
|
|
@ -42,16 +42,16 @@ impl MockStream {
|
|||
}
|
||||
|
||||
impl Read for MockStream {
|
||||
fn read(&mut self, buf: &mut[u8]) -> Result<usize> {
|
||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
|
||||
if self.read_delay > 0 {
|
||||
self.read_delay -= 1;
|
||||
return Ok(0)
|
||||
return Ok(0);
|
||||
}
|
||||
if self.err_on_read {
|
||||
return Err(Error::new(ErrorKind::Other, "MockStream Error"))
|
||||
return Err(Error::new(ErrorKind::Other, "MockStream Error"));
|
||||
}
|
||||
if self.read_pos >= self.read_buf.len() {
|
||||
return Err(Error::new(ErrorKind::UnexpectedEof, "EOF"))
|
||||
return Err(Error::new(ErrorKind::UnexpectedEof, "EOF"));
|
||||
}
|
||||
let write_len = min(buf.len(), self.read_buf.len() - self.read_pos);
|
||||
let max_pos = self.read_pos + write_len;
|
||||
|
|
|
|||
46
src/parse.rs
46
src/parse.rs
|
|
@ -7,7 +7,7 @@ pub fn parse_authenticate_response(line: String) -> Result<String> {
|
|||
let authenticate_regex = Regex::new("^+(.*)\r\n").unwrap();
|
||||
|
||||
for cap in authenticate_regex.captures_iter(line.as_str()) {
|
||||
let data = cap.get(1).map(|x|x.as_str()).unwrap_or("");
|
||||
let data = cap.get(1).map(|x| x.as_str()).unwrap_or("");
|
||||
return Ok(String::from(data));
|
||||
}
|
||||
|
||||
|
|
@ -20,7 +20,7 @@ pub fn parse_capability(lines: Vec<String>) -> Result<Vec<String>> {
|
|||
//Check Ok
|
||||
match parse_response_ok(lines.clone()) {
|
||||
Ok(_) => (),
|
||||
Err(e) => return Err(e)
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
|
||||
for line in lines.iter() {
|
||||
|
|
@ -37,7 +37,7 @@ pub fn parse_capability(lines: Vec<String>) -> Result<Vec<String>> {
|
|||
pub fn parse_response_ok(lines: Vec<String>) -> Result<()> {
|
||||
match parse_response(lines) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => return Err(e)
|
||||
Err(e) => return Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -45,11 +45,11 @@ pub fn parse_response(lines: Vec<String>) -> Result<Vec<String>> {
|
|||
let regex = Regex::new(r"^([a-zA-Z0-9]+) (OK|NO|BAD)(.*)").unwrap();
|
||||
let last_line = match lines.last() {
|
||||
Some(l) => l,
|
||||
None => return Err(Error::Parse(ParseError::StatusResponse(lines.clone())))
|
||||
None => return Err(Error::Parse(ParseError::StatusResponse(lines.clone()))),
|
||||
};
|
||||
|
||||
for cap in regex.captures_iter(last_line) {
|
||||
let response_type = cap.get(2).map(|x|x.as_str()).unwrap_or("");
|
||||
let response_type = cap.get(2).map(|x| x.as_str()).unwrap_or("");
|
||||
match response_type {
|
||||
"OK" => return Ok(lines.clone()),
|
||||
"BAD" => return Err(Error::BadResponse(lines.clone())),
|
||||
|
|
@ -79,7 +79,7 @@ pub fn parse_select_or_examine(lines: Vec<String>) -> Result<Mailbox> {
|
|||
//Check Ok
|
||||
match parse_response_ok(lines.clone()) {
|
||||
Ok(_) => (),
|
||||
Err(e) => return Err(e)
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
|
||||
let mut mailbox = Mailbox::default();
|
||||
|
|
@ -118,22 +118,41 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn parse_capability_test() {
|
||||
let expected_capabilities = vec![String::from("IMAP4rev1"), String::from("STARTTLS"), String::from("AUTH=GSSAPI"), String::from("LOGINDISABLED")];
|
||||
let lines = vec![String::from("* CAPABILITY IMAP4rev1 STARTTLS AUTH=GSSAPI LOGINDISABLED\r\n"), String::from("a1 OK CAPABILITY completed\r\n")];
|
||||
let expected_capabilities = vec![
|
||||
String::from("IMAP4rev1"),
|
||||
String::from("STARTTLS"),
|
||||
String::from("AUTH=GSSAPI"),
|
||||
String::from("LOGINDISABLED"),
|
||||
];
|
||||
let lines = vec![
|
||||
String::from(
|
||||
"* CAPABILITY IMAP4rev1 STARTTLS AUTH=GSSAPI LOGINDISABLED\r\n",
|
||||
),
|
||||
String::from("a1 OK CAPABILITY completed\r\n"),
|
||||
];
|
||||
let capabilities = parse_capability(lines).unwrap();
|
||||
assert!(capabilities == expected_capabilities, "Unexpected capabilities parse response");
|
||||
assert!(
|
||||
capabilities == expected_capabilities,
|
||||
"Unexpected capabilities parse response"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn parse_capability_invalid_test() {
|
||||
let lines = vec![String::from("* JUNK IMAP4rev1 STARTTLS AUTH=GSSAPI LOGINDISABLED\r\n"), String::from("a1 OK CAPABILITY completed\r\n")];
|
||||
let lines = vec![
|
||||
String::from("* JUNK IMAP4rev1 STARTTLS AUTH=GSSAPI LOGINDISABLED\r\n"),
|
||||
String::from("a1 OK CAPABILITY completed\r\n"),
|
||||
];
|
||||
parse_capability(lines).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parse_response_test() {
|
||||
let lines = vec![String::from("* LIST (\\HasNoChildren) \".\" \"INBOX\"\r\n"), String::from("a2 OK List completed.\r\n")];
|
||||
let lines = vec![
|
||||
String::from("* LIST (\\HasNoChildren) \".\" \"INBOX\"\r\n"),
|
||||
String::from("a2 OK List completed.\r\n"),
|
||||
];
|
||||
let expected_lines = lines.clone();
|
||||
let actual_lines = parse_response(lines).unwrap();
|
||||
assert!(expected_lines == actual_lines, "Unexpected parse response");
|
||||
|
|
@ -142,7 +161,10 @@ mod tests {
|
|||
#[test]
|
||||
#[should_panic]
|
||||
fn parse_response_invalid_test() {
|
||||
let lines = vec![String::from("* LIST (\\HasNoChildren) \".\" \"INBOX\"\r\n"), String::from("a2 BAD broken.\r\n")];
|
||||
let lines = vec![
|
||||
String::from("* LIST (\\HasNoChildren) \".\" \"INBOX\"\r\n"),
|
||||
String::from("a2 BAD broken.\r\n"),
|
||||
];
|
||||
parse_response(lines).unwrap();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue