<feed xmlns='http://www.w3.org/2005/Atom'>
<title>mutt-alias-auto-add/src, branch v0.0.2</title>
<subtitle>A display filter for Mutt to automatically add aliases for emails that you read</subtitle>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/mutt-alias-auto-add/'/>
<entry>
<title>main: Ignore errors, don't write to STDERR</title>
<updated>2016-04-27T20:46:07+00:00</updated>
<author>
<name>Teddy Wing</name>
</author>
<published>2016-04-27T20:46:07+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/mutt-alias-auto-add/commit/?id=f45f00cbbe32d473deb4e23e8944a5a61e5f8e45'/>
<id>f45f00cbbe32d473deb4e23e8944a5a61e5f8e45</id>
<content type='text'>
Well, after all that error handling I'm going to have to remove error
output. The problem was that this STDERR output interfered with the
output of the email in Mutt. When viewing a message, the screen would
become mangled (for certain messages), and I'd have to refresh (Ctrl-L)
the view.

After initially thinking this was because I was using `println!` instead
of flushing a full buffer to STDOUT, I just now realised that my output
to STDERR could be causing the problem. Sure enough, removing the STDERR
output fixed the issue.

This is certainly not ideal, so in the long term we'll probably want to
add some kind of logging mechanism so that users actually have
visibility into errors. But for now and for my own personal purposes, I
think this works. And at least it gets me around the immediate annoying
screen mangling issue.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Well, after all that error handling I'm going to have to remove error
output. The problem was that this STDERR output interfered with the
output of the email in Mutt. When viewing a message, the screen would
become mangled (for certain messages), and I'd have to refresh (Ctrl-L)
the view.

After initially thinking this was because I was using `println!` instead
of flushing a full buffer to STDOUT, I just now realised that my output
to STDERR could be causing the problem. Sure enough, removing the STDERR
output fixed the issue.

This is certainly not ideal, so in the long term we'll probably want to
add some kind of logging mechanism so that users actually have
visibility into errors. But for now and for my own personal purposes, I
think this works. And at least it gets me around the immediate annoying
screen mangling issue.
</pre>
</div>
</content>
</entry>
<entry>
<title>Read aliases file as bytes and convert to string</title>
<updated>2016-04-27T09:50:40+00:00</updated>
<author>
<name>Teddy Wing</name>
</author>
<published>2016-04-27T09:50:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/mutt-alias-auto-add/commit/?id=78e7b4c607d8fc3b35f90ed88614093bda437195'/>
<id>78e7b4c607d8fc3b35f90ed88614093bda437195</id>
<content type='text'>
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: &amp;[u8]) -&gt; 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 `&amp;[u8]`,
        found `core::result::Result&lt;collections::string::String, std::io::error::Error&gt;`
    (expected &amp;-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 `&amp;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 &amp;u8.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
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: &amp;[u8]) -&gt; 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 `&amp;[u8]`,
        found `core::result::Result&lt;collections::string::String, std::io::error::Error&gt;`
    (expected &amp;-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 `&amp;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 &amp;u8.
</pre>
</div>
</content>
</entry>
<entry>
<title>test: Fix `write_to_file` race condition</title>
<updated>2016-04-24T13:39:14+00:00</updated>
<author>
<name>Teddy Wing</name>
</author>
<published>2016-04-24T13:39:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/mutt-alias-auto-add/commit/?id=79e78aaa7c0c77064264ffdad0c3172aa0f5c376'/>
<id>79e78aaa7c0c77064264ffdad0c3172aa0f5c376</id>
<content type='text'>
Have each `write_to_file` test pass in a custom filename to the helper
function. This way each test has its own file to deal with, eliminating
the race condition when running tests in parallel (the default).
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Have each `write_to_file` test pass in a custom filename to the helper
function. This way each test has its own file to deal with, eliminating
the race condition when running tests in parallel (the default).
</pre>
</div>
</content>
</entry>
<entry>
<title>Write alias even if we haven't found a matching one</title>
<updated>2016-04-24T13:31:25+00:00</updated>
<author>
<name>Teddy Wing</name>
</author>
<published>2016-04-24T13:31:25+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/mutt-alias-auto-add/commit/?id=2e844b5c528a39e75702d0b412b0396080fa103e'/>
<id>2e844b5c528a39e75702d0b412b0396080fa103e</id>
<content type='text'>
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.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
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.
</pre>
</div>
</content>
</entry>
<entry>
<title>`write_to_file` test: Extract append lines to closure</title>
<updated>2016-04-24T12:44:04+00:00</updated>
<author>
<name>Teddy Wing</name>
</author>
<published>2016-04-24T12:44:04+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/mutt-alias-auto-add/commit/?id=7c9439bc11ae95b6f2da59eabf2950d15df4d558'/>
<id>7c9439bc11ae95b6f2da59eabf2950d15df4d558</id>
<content type='text'>
We want to be able to write a test that ensures aliases can be written
to the file even if they don't already exist.

To do this, I want to be able to reuse the code in the helper function.
We can't use the code that appends to the file because this is relevant
only to the `alias_write_to_file_must_write_given_alias_to_file` test
(which I just realised should actually be renamed to something more
specific).

In order to run this code without requiring it to be in the helper
function, extract it to a closure that gets passed to the helper.

We need to pass `alias` into the function explicitly in order to use it
otherwise we get an error on an immutable borrow.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
We want to be able to write a test that ensures aliases can be written
to the file even if they don't already exist.

To do this, I want to be able to reuse the code in the helper function.
We can't use the code that appends to the file because this is relevant
only to the `alias_write_to_file_must_write_given_alias_to_file` test
(which I just realised should actually be renamed to something more
specific).

In order to run this code without requiring it to be in the helper
function, extract it to a closure that gets passed to the helper.

We need to pass `alias` into the function explicitly in order to use it
otherwise we get an error on an immutable borrow.
</pre>
</div>
</content>
</entry>
<entry>
<title>Extract `alias_write_to_file` test function contents to helper</title>
<updated>2016-04-24T10:36:32+00:00</updated>
<author>
<name>Teddy Wing</name>
</author>
<published>2016-04-24T10:36:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/mutt-alias-auto-add/commit/?id=66193af4e53799299c04ecf8715e44693f1bff8a'/>
<id>66193af4e53799299c04ecf8715e44693f1bff8a</id>
<content type='text'>
Create a new helper function that does the work of
`alias_write_to_file_must_write_given_alias_to_file`. We want to be able
to add another test of the `write_to_file` method that does the same
thing but for non-preexisting aliases. Making a helper method will allow
us to avoid duplicating work.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Create a new helper function that does the work of
`alias_write_to_file_must_write_given_alias_to_file`. We want to be able
to add another test of the `write_to_file` method that does the same
thing but for non-preexisting aliases. Making a helper method will allow
us to avoid duplicating work.
</pre>
</div>
</content>
</entry>
<entry>
<title>Add a documentation comment to our crate</title>
<updated>2016-04-24T10:13:23+00:00</updated>
<author>
<name>Teddy Wing</name>
</author>
<published>2016-04-24T10:13:23+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/mutt-alias-auto-add/commit/?id=15759804bd3be99fc6374ee993038440267fdfb5'/>
<id>15759804bd3be99fc6374ee993038440267fdfb5</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>main: Change `unwrap` to `expect`</title>
<updated>2016-04-24T09:48:05+00:00</updated>
<author>
<name>Teddy Wing</name>
</author>
<published>2016-04-24T09:48:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/mutt-alias-auto-add/commit/?id=b11af1eccb5116b8901dd999f48210ce955ea9b7'/>
<id>b11af1eccb5116b8901dd999f48210ce955ea9b7</id>
<content type='text'>
Give us a better error message if a failure ever happens here. Was
inspired by my experience in 2d1f7031f03194fbceffc15b1d6376abea243e22,
where the `unwrap` calls gave no useful information.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Give us a better error message if a failure ever happens here. Was
inspired by my experience in 2d1f7031f03194fbceffc15b1d6376abea243e22,
where the `unwrap` calls gave no useful information.
</pre>
</div>
</content>
</entry>
<entry>
<title>Move `Alias` to separate alias module</title>
<updated>2016-04-24T09:40:45+00:00</updated>
<author>
<name>Teddy Wing</name>
</author>
<published>2016-04-24T09:40:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/mutt-alias-auto-add/commit/?id=afc01ecb67dd978879d423866d33ac0c526151f4'/>
<id>afc01ecb67dd978879d423866d33ac0c526151f4</id>
<content type='text'>
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
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
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
</pre>
</div>
</content>
</entry>
<entry>
<title>Move `write_alias` function to `Alias#write_to_file`</title>
<updated>2016-04-24T09:17:19+00:00</updated>
<author>
<name>Teddy Wing</name>
</author>
<published>2016-04-24T09:17:19+00:00</published>
<link rel='alternate' type='text/html' href='https://git.teddywing.com/mutt-alias-auto-add/commit/?id=2d1f7031f03194fbceffc15b1d6376abea243e22'/>
<id>2d1f7031f03194fbceffc15b1d6376abea243e22</id>
<content type='text'>
Expand the responsibility of `Alias#write_to_file` so that it performs
what it used to do plus all of what `write_alias` did.

This allows us to consolidate the functionality into a single method,
and move it into the `Alias` implementation.

The change required some modification to our `write_to_file` test:

* Create our test alias as mutable
* Write a new alias to the test file based on our test alias but with a
  different email. This allows the `write_to_file` method to work
  without erroring with an `AliasSearchError::NotFound`.
* Needed to `derive(Clone)` on `Alias` in order to be able to easily
  clone it into the new near-duplicate alias.
* Change our `unwrap()` calls to `expect()` to make it easier to see
  where exactly we panicked. Otherwise I didn't really have any way of
  knowing.
* Add some comments for clarity
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Expand the responsibility of `Alias#write_to_file` so that it performs
what it used to do plus all of what `write_alias` did.

This allows us to consolidate the functionality into a single method,
and move it into the `Alias` implementation.

The change required some modification to our `write_to_file` test:

* Create our test alias as mutable
* Write a new alias to the test file based on our test alias but with a
  different email. This allows the `write_to_file` method to work
  without erroring with an `AliasSearchError::NotFound`.
* Needed to `derive(Clone)` on `Alias` in order to be able to easily
  clone it into the new near-duplicate alias.
* Change our `unwrap()` calls to `expect()` to make it easier to see
  where exactly we panicked. Otherwise I didn't really have any way of
  knowing.
* Add some comments for clarity
</pre>
</div>
</content>
</entry>
</feed>
