Input/output for a simple Brainfuck interpreter
a better/clearer way to implement the read_cell and write_cell methods?


What you have seems pretty good to me. Rust's IO methods rely on having a buffer to read into. In many cases, you might see a single byte read with something like

let mut buf = [0; 1]; 
reader.read(&amp;mut buf).unwrap();


In your case, you already have a buffer, so you might as well read directly into it.


  Can I write the same test without having to nest scopes?


Nope. Let's comment out the nested braces and look at the error messages:

error: cannot borrow `output` as immutable because it is also
       borrowed as mutable

match ( &amp; ( $ left ) , &amp; ( $ right ) ) {
                         ^~~~~~~~~~~
note: in expansion of assert_eq!


We are attempting to immutably borrow something that's already borrowed. The compiler is kind enough to show us where the borrow occurs:

note: previous borrow of `output` occurs here; the mutable borrow
      prevents subsequent moves, borrows, or modification of
      `output` until the borrow ends    

let mut machine = Machine::new(input, &amp;mut output);
                                           ^~~~~~


And where it ends:

note: previous borrow ends here

fn test_write_cell() {
...
}
^


When there is an outstanding mutable borrow, Rust only that borrow to exist. This removes whole classes of bugs around "spooky action at a distance" as well as potential data races. The extra braces provide a lifetime that the borrow can live during; once the block is exited, the borrow is no longer needed.

The only solution I know of is to use what I like to call an exploder. If you are familiar with constructors and destructors, then an exploder is like a destructor that returns values. There's a common pattern in the standard library with methods called into_inner. Here's how it could look for your code:

impl&lt;In: Read, Out: Write&gt; Machine&lt;In, Out&gt; {
    pub fn into_inner(self) -&gt; (In, Out) {
        (self.input, self.output)
    }
}

fn test_write_cell() {
    let input = "".as_bytes();
    let output = vec![];

    let mut machine = Machine::new(input, output);
    machine.memory[machine.pointer] = 1;
    machine.write_cell();

    let (_, output) = machine.into_inner();

    assert_eq!(vec![1], output);
}