Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating a read stream over a string

I have a function that takes an input stream, processes its data, and then returns something, basically a more complicated version of this:

fn read_number_from_stream(input: &mut io::BufRead) -> io::Result<u32> {
  // code that does something useful here
  Ok(0)
}

Now I want to write a test for this function.

#[test]
fn input_with_zero_returns_zero() {
  let test_input = read_from_string("0\n");
  assert_eq!(Ok(0), read_number_from_stream(test_input));
}

How do I implement read_from_string? Older versions of Rust apparently provided std::io::mem::MemReader, but the entire std::io::mem module seems to be gone in more recent versions of Rust (I'm using the unstable 1.5 branch).

like image 480
Sebastian Redl Avatar asked Oct 29 '15 23:10

Sebastian Redl


1 Answers

The documentation for each trait lists the available implementations. Here's the documentation page for BufRead. We can see that &'a [u8] (a slice of bytes) implements BufRead. We can obtain a slice of bytes from a string and pass a mutable reference to that slice to read_number_from_stream:

use std::io;

fn read_number_from_stream(input: &mut io::BufRead) -> io::Result<u32> {
    // code that does something useful here
    Ok(0)
}

fn read_from_string(s: &str) -> &[u8] {
    s.as_bytes()
}

fn main() {
    let mut test_input = read_from_string("0\n");
    read_number_from_stream(&mut test_input);
}

If the buffer is not expected to contain UTF-8, or you just care about a particular ASCII-compatible subset of characters, you may want to define the test input as a byte string, rather than as a normal string. A byte string is written like a normal string, prefixed with b, e.g. b"0\n". The type of a byte string is &[u8; N], where N is the length of the string. Since that type doesn't implement BufRead, we need to cast it to &[u8].

fn main() {
    let mut test_input = b"0\n" as &[u8];
    read_number_from_stream(&mut test_input);
}
like image 114
Francis Gagné Avatar answered Sep 20 '22 17:09

Francis Gagné