aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeddy Wing2016-04-24 05:40:45 -0400
committerTeddy Wing2016-04-24 05:40:45 -0400
commitafc01ecb67dd978879d423866d33ac0c526151f4 (patch)
tree262d27a7ec2c80ab257f53008df57ac5fd16c20f
parent2d1f7031f03194fbceffc15b1d6376abea243e22 (diff)
downloadmutt-alias-auto-add-afc01ecb67dd978879d423866d33ac0c526151f4.tar.bz2
Move `Alias` to separate alias module
Take all of our Alias code, functions, errors, etc. and move them into their own module. This removes some clutter from our `main.rs` file and makes things better organised. Now all the alias code lives in its own dedicated place. Update our test file imports to match this change. Updates to alias code: * Reordered imports alphabetically * Made `Alias` public * Made `AliasSearchError` public * Made all methods on `Alias` public
-rw-r--r--src/alias.rs152
-rw-r--r--src/main.rs155
-rw-r--r--src/tests.rs2
3 files changed, 157 insertions, 152 deletions
diff --git a/src/alias.rs b/src/alias.rs
new file mode 100644
index 0000000..8a66db8
--- /dev/null
+++ b/src/alias.rs
@@ -0,0 +1,152 @@
+use std::error::{self, Error};
+use std::fs::{File, OpenOptions};
+use std::fmt;
+use std::io::{self, BufRead, BufReader, Write};
+use std::path::Path;
+
+#[derive(Clone)]
+pub struct Alias {
+ pub alias: String,
+ pub name: String,
+ pub email: String,
+}
+
+impl Alias {
+ pub fn new(email: &str) -> Alias {
+ let mut split: Vec<&str> = email.split_whitespace().collect();
+
+ // Remove "From: "
+ split.remove(0);
+
+ let mut alias = String::new();
+ let mut name = String::new();
+ let mut email = String::new();
+
+ if split.len() == 1 {
+ alias = split[0].to_lowercase().to_string();
+ email = split[0].to_string();
+ } else if split.len() == 2 {
+ alias = split[0].to_lowercase().to_string();
+ name = split[0].to_string();
+ email = split[1].to_string();
+ } else if split.len() > 2 {
+ alias = format!("{}-{}", split[split.len() - 2], split[0]).to_lowercase().to_string();
+ name = split[0..(split.len() - 1)].join(" ");
+ email = split[split.len() - 1].to_string();
+ }
+
+ alias = alias.replace(',', "");
+ alias = alias.replace('\'', "");
+ alias = alias.replace('"', "");
+
+ Alias { alias: alias, name: name, email: email }
+ }
+
+ pub fn to_string(&self) -> String {
+ if self.name.is_empty() {
+ format!("alias {} {}", self.alias, self.email)
+ } else {
+ format!("alias {} {} {}", self.alias, self.name, self.email)
+ }
+ }
+
+ pub fn find_in_file<P: AsRef<Path>>(&self, file: P) -> Result<Vec<String>, AliasSearchError> {
+ let mut matches = Vec::new();
+ let f = try!(File::open(file));
+ let file = BufReader::new(&f);
+ for line in file.lines() {
+ let line = try!(line);
+ let split: Vec<&str> = line.split_whitespace().collect();
+
+ if line.contains(&self.email) {
+ return Err(AliasSearchError::EmailExists)
+ }
+
+ if split[1].starts_with(&self.alias) {
+ matches.push(split[1].to_owned());
+ }
+ }
+
+ if matches.is_empty() {
+ Err(AliasSearchError::NotFound)
+ } else {
+ Ok(matches)
+ }
+ }
+
+ pub fn write_to_file<P: AsRef<Path>>(&mut self, file: P) -> Result<(), AliasSearchError> {
+ let similar_aliases = try!(self.find_in_file(&file));
+ self.update_alias_id(similar_aliases);
+
+ let mut f = try!(OpenOptions::new().append(true).open(file));
+ try!(f.write_all(format!("{}\n", self.to_string()).as_bytes()));
+
+ Ok(())
+ }
+
+ pub fn update_alias_id(&mut self, similar_aliases: Vec<String>) {
+ if !similar_aliases.is_empty() {
+ self.alias = format!("{}-{}", self.alias, similar_aliases.len() + 1);
+ }
+ }
+}
+
+#[derive(Debug)]
+pub enum AliasSearchError {
+ NotFound,
+ EmailExists,
+ Io(io::Error),
+}
+
+impl fmt::Display for AliasSearchError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ AliasSearchError::NotFound => writeln!(f, "{}", self.description()),
+ AliasSearchError::EmailExists => writeln!(f, "{}", self.description()),
+ AliasSearchError::Io(ref err) => writeln!(f, "IO error: {}", err),
+ }
+ }
+}
+
+impl error::Error for AliasSearchError {
+ fn description(&self) -> &str {
+ match *self {
+ AliasSearchError::NotFound => "Alias could not be found in aliases file",
+ AliasSearchError::EmailExists => "Email already exists in aliases file",
+ AliasSearchError::Io(ref err) => err.description(),
+ }
+ }
+
+ fn cause(&self) -> Option<&error::Error> {
+ match *self {
+ AliasSearchError::Io(ref err) => Some(err),
+ _ => None,
+ }
+ }
+}
+
+impl From<io::Error> for AliasSearchError {
+ fn from(err: io::Error) -> AliasSearchError {
+ AliasSearchError::Io(err)
+ }
+}
+
+#[cfg(test)]
+impl PartialEq<AliasSearchError> for AliasSearchError {
+ fn eq(&self, other: &AliasSearchError) -> bool {
+ match *self {
+ AliasSearchError::NotFound => match *other {
+ AliasSearchError::NotFound => true,
+ _ => false,
+ },
+ AliasSearchError::EmailExists => match *other {
+ AliasSearchError::EmailExists => true,
+ _ => false,
+ },
+ AliasSearchError::Io(_) => match *other {
+ AliasSearchError::Io(_) => true,
+ _ => false,
+ },
+ }
+ }
+}
diff --git a/src/main.rs b/src/main.rs
index 91545bf..0732f6d 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,159 +1,12 @@
use std::env;
-use std::error::{self, Error};
-use std::io::{self, BufRead, BufReader, Write};
-use std::fmt;
-use std::fs::{File, OpenOptions};
-use std::path::Path;
+use std::io::{self, BufRead, Write};
+
+mod alias;
#[cfg(test)]
mod tests;
-#[derive(Clone)]
-struct Alias {
- alias: String,
- name: String,
- email: String,
-}
-
-impl Alias {
- fn new(email: &str) -> Alias {
- let mut split: Vec<&str> = email.split_whitespace().collect();
-
- // Remove "From: "
- split.remove(0);
-
- let mut alias = String::new();
- let mut name = String::new();
- let mut email = String::new();
-
- if split.len() == 1 {
- alias = split[0].to_lowercase().to_string();
- email = split[0].to_string();
- } else if split.len() == 2 {
- alias = split[0].to_lowercase().to_string();
- name = split[0].to_string();
- email = split[1].to_string();
- } else if split.len() > 2 {
- alias = format!("{}-{}", split[split.len() - 2], split[0]).to_lowercase().to_string();
- name = split[0..(split.len() - 1)].join(" ");
- email = split[split.len() - 1].to_string();
- }
-
- alias = alias.replace(',', "");
- alias = alias.replace('\'', "");
- alias = alias.replace('"', "");
-
- Alias { alias: alias, name: name, email: email }
- }
-
- fn to_string(&self) -> String {
- if self.name.is_empty() {
- format!("alias {} {}", self.alias, self.email)
- } else {
- format!("alias {} {} {}", self.alias, self.name, self.email)
- }
- }
-
- fn find_in_file<P: AsRef<Path>>(&self, file: P) -> Result<Vec<String>, AliasSearchError> {
- let mut matches = Vec::new();
- let f = try!(File::open(file));
- let file = BufReader::new(&f);
- for line in file.lines() {
- let line = try!(line);
- let split: Vec<&str> = line.split_whitespace().collect();
-
- if line.contains(&self.email) {
- return Err(AliasSearchError::EmailExists)
- }
-
- if split[1].starts_with(&self.alias) {
- matches.push(split[1].to_owned());
- }
- }
-
- if matches.is_empty() {
- Err(AliasSearchError::NotFound)
- } else {
- Ok(matches)
- }
- }
-
- fn write_to_file<P: AsRef<Path>>(&mut self, file: P) -> Result<(), AliasSearchError> {
- let similar_aliases = try!(self.find_in_file(&file));
- self.update_alias_id(similar_aliases);
-
- let mut f = try!(OpenOptions::new().append(true).open(file));
- try!(f.write_all(format!("{}\n", self.to_string()).as_bytes()));
-
- Ok(())
- }
-
- fn update_alias_id(&mut self, similar_aliases: Vec<String>) {
- if !similar_aliases.is_empty() {
- self.alias = format!("{}-{}", self.alias, similar_aliases.len() + 1);
- }
- }
-}
-
-#[derive(Debug)]
-enum AliasSearchError {
- NotFound,
- EmailExists,
- Io(io::Error),
-}
-
-impl fmt::Display for AliasSearchError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- match *self {
- AliasSearchError::NotFound => writeln!(f, "{}", self.description()),
- AliasSearchError::EmailExists => writeln!(f, "{}", self.description()),
- AliasSearchError::Io(ref err) => writeln!(f, "IO error: {}", err),
- }
- }
-}
-
-impl error::Error for AliasSearchError {
- fn description(&self) -> &str {
- match *self {
- AliasSearchError::NotFound => "Alias could not be found in aliases file",
- AliasSearchError::EmailExists => "Email already exists in aliases file",
- AliasSearchError::Io(ref err) => err.description(),
- }
- }
-
- fn cause(&self) -> Option<&error::Error> {
- match *self {
- AliasSearchError::Io(ref err) => Some(err),
- _ => None,
- }
- }
-}
-
-impl From<io::Error> for AliasSearchError {
- fn from(err: io::Error) -> AliasSearchError {
- AliasSearchError::Io(err)
- }
-}
-
-#[cfg(test)]
-impl PartialEq<AliasSearchError> for AliasSearchError {
- fn eq(&self, other: &AliasSearchError) -> bool {
- match *self {
- AliasSearchError::NotFound => match *other {
- AliasSearchError::NotFound => true,
- _ => false,
- },
- AliasSearchError::EmailExists => match *other {
- AliasSearchError::EmailExists => true,
- _ => false,
- },
- AliasSearchError::Io(_) => match *other {
- AliasSearchError::Io(_) => true,
- _ => false,
- },
- }
- }
-}
+use alias::*;
fn print_usage(program: &str) {
println!("Usage: {} FILE", program);
diff --git a/src/tests.rs b/src/tests.rs
index 21cf147..708121e 100644
--- a/src/tests.rs
+++ b/src/tests.rs
@@ -1,7 +1,7 @@
use std::fs::{self, File, OpenOptions};
use std::io::{Read, Write};
-use super::{Alias, AliasSearchError};
+use alias::{Alias, AliasSearchError};
#[test]
fn new_alias_with_only_email() {