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)readsndata items from input and stores them in a Vec. -
read!(m, n)readsm * ndata items from input and stores them in a Mat,which consists of
mVecs, each containingndata 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:3use 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]]);