aboutsummaryrefslogtreecommitdiffstats
path: root/src/alias.rs
AgeCommit message (Collapse)Author
2016-04-27Read aliases file as bytes and convert to stringTeddy Wing
Discovered that my Mutt aliases file uses the latin1 character encoding. That caused a "stream did not contain valid UTF-8" error when trying to read the file in the `Alias#find_in_file` function. This error was ostensibly triggered by a `str::from_utf8` call in the standard library (https://github.com/rust-lang/rust/blob/2174bd97c1458d89a87eb2b614135d7ad68d6f18/src/libstd/io/mod.rs#L315-L338). I ended up finding this Stack Overflow answer with an easy solution: http://stackoverflow.com/questions/28169745/what-are-the-options-to-convert-iso-8859-1-latin-1-to-a-string-utf-8/28175593#28175593 fn latin1_to_string(s: &[u8]) -> String { s.iter().map(|c| c as char).collect() } Since latin1 is a subset of Unicode, we can just read the bytes from the file and typecast them to Rust chars (which are UTF-8). That gives us the opportunity to easily get the text into an encoding that we can actually work with in Rust. At first I got frustrated because the suggestion didn't compile for me. It was suggested in January 2015, before Rust 1.0, so perhaps that factors into the error I was getting. Here it is: src/alias.rs:59:41: 59:45 error: mismatched types: expected `&[u8]`, found `core::result::Result<collections::string::String, std::io::error::Error>` (expected &-ptr, found enum `core::result::Result`) [E0308] src/alias.rs:59 let line = latin1_to_string(line); ^~~~ src/alias.rs:59:41: 59:45 help: run `rustc --explain E0308` to see a detailed explanation src/alias.rs:99:22: 99:31 error: only `u8` can be cast as `char`, not `&u8` src/alias.rs:99 s.iter().map(|c| c as char).collect() ^~~~~~~~~ error: aborting due to 2 previous errors A recommendation from 'niconii' Mozilla#rust-beginners was to use the Encoding library in order to do the conversion (https://github.com/lifthrasiir/rust-encoding). That certainly seems more robust and would be a good idea to try if this change doesn't work out in the long term. But the Stack Overflow answer just seemed so short and sweet that I really didn't like the idea of adding a dependency if I could get what I wanted with 3 lines of code. Finally took another look and reworked the suggested code to take a vector (which is what `BufReader#split` gives us) and clone the u8 characters to clear the compiler error of not being able to cast an &u8.
2016-04-24Write alias even if we haven't found a matching oneTeddy Wing
If we get an `AliasSearchError::NotFound` error we still want to write the alias to the file. After all, it's an email we haven't encountered yet so we should store an alias for it. If the email exists, we can do what we were doing before and change the current alias to be unique. Rename our "append" `write_to_file` test method to be a little more clear about its purpose. Create a new `write_to_file` test function that tests the case we're adding here. Note that having these two tests together seems to cause a race condition because they're both using the same temporary test file. If we run tests with `RUST_TEST_THREADS=1 cargo test` then they pass. Will see about fixing that next.
2016-04-24Move `Alias` to separate alias moduleTeddy Wing
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