read

Macro read 

Source
macro_rules! read {
    (@ $(,)?; src = $src:expr; fmt = $fmt:expr) => { ... };
    (@ $dim0:expr $(, $dims:expr)* $(,)?; src = $src:expr; fmt = $fmt:expr) => { ... };
    ($(,)? $(; src = $src:expr)? $(; fmt = $fmt:expr)?) => { ... };
    ($dim0:expr $(, $dims:expr)* $(,)? $(; src = $src:expr)? $(; fmt = $fmt:expr)?) => { ... };
    ($(,)? $(; src = $src:expr)? ; skip = $skip:expr) => { ... };
    ($dim0:expr $(, $dims:expr)* $(,)? $(; src = $src:expr)? ; skip = $skip:expr) => { ... };
}
Expand description

Read a single data item, a Vec or a Mat from input using ReadInto.

The intended grammar is:

$($dims:expr),* $(,)? $(; src = $src:expr)? $(; fmt = $fmt:expr)?
  • read!() reads a single data item from input.

  • read!(n) reads n data items from input and stores them in a Vec.

  • read!(m, n) reads m * n data items from input and stores them in a Mat,

    which consists of m Vecs, each containing n data items.

And the reader will always respect your size hint, and if you pass a size larger that the actual data in current line, it will go on to the next line and read as many as the size hint.

§Example

use iof::read;
let a: usize = read!();
let b: Vec<usize> = read!(3);
let c: Vec<Vec<usize>> = read!(2, 3);

§Notes

This macro accepts even higher dimensions, such as read!(m, n, o, p), but as this creates a nested Vec, this may cause performance concerns.

What’s more, you can pass a dynamic value to read! like read!(m, f()), which can create a nested Vec with a non-uniform length.

Given the input:

1
2 3
4 5 6

1 2 3
4 5 6
7 8 9

10 11 12
13 14 15
16 17 18

19 20 21
22 23 24
25 26 27

1,2,3
1;2;3
1:2:3
use iof::read;

fn main() {
    let mut i = 0usize;
    let mut f = || {
        i += 1;
        i
    };
    let m: Vec<Vec<u32>> = read!(3, f());
    assert_eq!(m, vec![vec![1], vec![2, 3], vec![4, 5, 6]]);

    let m: Vec<Vec<Vec<i32>>> = read!(3, 3, 3);
    assert_eq!(
        m,
        [
            [[1, 2, 3], [4, 5, 6], [7, 8, 9],],
            [[10, 11, 12], [13, 14, 15], [16, 17, 18],],
            [[19, 20, 21], [22, 23, 24], [25, 26, 27],],
        ],
    );

    let v: Vec<i32> = read!(3; fmt = iof::fmt::csv());
    assert_eq!(v, [1, 2, 3]);

    let v: Vec<i32> = read!(3; skip = ";\r\n".chars());
    assert_eq!(v, [1, 2, 3]);

    let v: Vec<i32> = read!(3; skip = [':', '\r', '\n']);
    assert_eq!(v, [1, 2, 3]);
}

Also, you can specify the source (as long as it implements BufReadExt) via src = and format (as long as it implements Format) via fmt = for reading, and you can also specify the characters to skip via skip =, which is a shorthand for fmt = iof::fmt::skip($skip).

use iof::{fmt::csv, read, InputStream, Mat};

let a: usize = read!(; src = InputStream::new(b"42".as_slice()));
assert_eq!(a, 42);

let b: Vec<usize> = read!(3; src = InputStream::new(b"1 2 3".as_slice()));
assert_eq!(b, [1, 2, 3]);

let b: Vec<usize> = read!(3; src = InputStream::new(b"1, 2, 3".as_slice()); fmt = csv());
assert_eq!(b, [1, 2, 3]);

let s = b"010\n101";

let b: Mat<char> = read!(2, 3; src = InputStream::new(s.as_slice()); skip = [' ', ',', ';', '\n', '\r']);
assert_eq!(b, [['0', '1', '0'], ['1', '0', '1']]);

let s = b"1,2,3;4,5,6\r\n";

let b: Mat<usize> = read!(2, 3; src = InputStream::new(s.as_slice()); skip = [' ', ',', ';', '\r', '\n']);
assert_eq!(b, [[1, 2, 3], [4, 5, 6]]);

let b: Mat<usize> = read!(2, 3; src = InputStream::new(s.as_slice()); skip = " \t,;\r\n".chars());
assert_eq!(b, [[1, 2, 3], [4, 5, 6]]);