diff options
| -rw-r--r-- | src/main.rs | 86 | ||||
| -rw-r--r-- | src/tests.rs | 104 | ||||
| -rw-r--r-- | testdata/aliases | 2 | 
3 files changed, 171 insertions, 21 deletions
| diff --git a/src/main.rs b/src/main.rs index 49c30d3..77f230a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,6 @@ -use std::io::{self, BufRead}; +use std::io::{self, BufRead, BufReader, Write}; +use std::fs::{File, OpenOptions}; +use std::path::Path;  #[cfg(test)]  mod tests; @@ -47,37 +49,81 @@ impl Alias {              format!("alias {} {} {}", self.alias, self.name, self.email)          }      } + +    fn write_to_file<P: AsRef<Path>>(&self, file: P) -> Result<(), io::Error> { +        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); +        } +    }  }  fn handle_alias(s: &str) { -    let alias = build_alias(s);  } -fn build_alias(s: &str) -> String { -    let mut split: Vec<&str> = s.split_whitespace().collect(); +#[derive(Debug)] +enum AliasSearchError { +    NotFound, +    EmailExists, +    Io(io::Error), +} -    // Remove "From: " -    split.remove(0); +// impl fmt::Display for AliasSearchError {} +// impl error::Error for AliasSearchError {} -    let mut alias_line = String::from("alias "); -    let mut alias = String::new(); +impl From<io::Error> for AliasSearchError { +    fn from(err: io::Error) -> AliasSearchError { +        AliasSearchError::Io(err) +    } +} -    if split.len() == 1 { -        alias = format!("{} ", split[0].to_lowercase()); -    } else if split.len() == 2 { -        alias = format!("{} ", split[0].to_lowercase()); -    } else if split.len() > 2 { -        alias = format!("{}-{} ", split[split.len() - 2], split[0]).to_lowercase(); +#[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, +            }, +        }      } +} + +fn find_alias_in_file(alias: &Alias, file: &str) -> 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(); -    alias = alias.replace(',', ""); -    alias = alias.replace('\'', ""); -    alias = alias.replace('"', ""); +        if line.contains(&alias.email) { +            return Err(AliasSearchError::EmailExists) +        } -    alias_line.push_str(&alias); -    alias_line.push_str(&split.join(" ")); +        if split[1].starts_with(&alias.alias) { +            matches.push(split[1].to_owned()); +        } +    } -    alias_line +    if matches.is_empty() { +        Err(AliasSearchError::NotFound) +    } else { +        Ok(matches) +    }  }  fn main() { diff --git a/src/tests.rs b/src/tests.rs index c12bab1..2a6e264 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -1,4 +1,7 @@ -use super::Alias; +use std::fs::{self, File}; +use std::io::Read; + +use super::{Alias, AliasSearchError, find_alias_in_file};  #[test]  fn new_alias_with_only_email() { @@ -39,3 +42,102 @@ fn new_alias_with_special_characters() {          Alias::new("From: \"O'Strulson, Celty\" <celty@dollars.co>").to_string()      );  } + + +#[test] +fn find_alias_in_file_email_already_exists() { +    assert_eq!( +        Err(AliasSearchError::EmailExists), +        find_alias_in_file( +            &Alias { +                alias: "farnsworth-hubert".to_owned(), +                name: "Hubert Farnsworth".to_owned(), +                email: "<professor@planetexpress.com>".to_owned() +            }, +            "./testdata/aliases" +        ) +    ); +} + +#[test] +fn find_alias_in_file_alias_is_new() { +    assert_eq!( +        Err(AliasSearchError::NotFound), +        find_alias_in_file( +            &Alias { +                alias: "fry-philip".to_owned(), +                name: "Philip Fry".to_owned(), +                email: "<fry@planetexpress.com>".to_owned() +            }, +            "./testdata/aliases" +        ) +    ); +} + +#[test] +fn find_alias_in_file_finds_a_match() { +    assert_eq!( +        Ok(vec![ +            "farnsworth-hubert".to_owned(), +            "farnsworth-hubert-2".to_owned() +        ]), +        find_alias_in_file( +            &Alias { +                alias: "farnsworth-hubert".to_owned(), +                name: "Hubert Farnsworth".to_owned(), +                email: "<goodnewseveryone@planetexpress.com>".to_owned() +            }, +            "./testdata/aliases" +        ) +    ); +} + + +const update_alias_id_alias_identifier: &'static str = "hooves-derpy"; + +fn update_alias_id_sample_alias() -> Alias { +    Alias { +        alias: update_alias_id_alias_identifier.to_owned(), +        name: "Derpy Hooves".to_owned(), +        email: "derpyhooves@postmaster.pv".to_owned() +    } +} + +#[test] +fn update_alias_id_does_nothing_given_an_empty_vector() { +    let mut alias = update_alias_id_sample_alias(); +    alias.update_alias_id(vec![]); + +    assert_eq!(update_alias_id_alias_identifier, &alias.alias); +} + +#[test] +fn update_alias_id_increments_alias() { +    let mut alias = update_alias_id_sample_alias(); +    alias.update_alias_id(vec![ +        "hooves-derpy".to_owned(), +        "hooves-derpy-2".to_owned(), +        "hooves-derpy-3".to_owned(), +        "hooves-derpy-4".to_owned() +    ]); + +    assert_eq!("hooves-derpy-5", &alias.alias); +} + + +#[test] +fn alias_write_to_file_must_write_given_alias_to_file() { +    let alias = update_alias_id_sample_alias(); + +    let test_file = "./testdata/write_to_file"; +    fs::copy("./testdata/aliases", test_file).unwrap(); +    alias.write_to_file(test_file).unwrap(); + +    let mut f = File::open(test_file).unwrap(); +    let mut file_contents = String::new(); +    f.read_to_string(&mut file_contents).unwrap(); +    let file_contents: Vec<&str> = file_contents.split('\n').collect(); +    fs::remove_file(test_file).unwrap(); + +    assert_eq!(alias.to_string(), file_contents[file_contents.len() - 2]); +} diff --git a/testdata/aliases b/testdata/aliases new file mode 100644 index 0000000..d9c167a --- /dev/null +++ b/testdata/aliases @@ -0,0 +1,2 @@ +alias farnsworth-hubert Hubert Farnsworth <professor@planetexpress.com> +alias farnsworth-hubert-2 Hubert Farnsworth <davincifan@planetexpress.com> | 
