concise_scanf_like_input/
lib.rs

1use std::io::{self, Read, Write};
2
3/// Reads a sample input into a buffer, separating the the lines from each other.
4/// On Unix, one needs to enter C-D to mark the end of input.
5///
6/// # Examples
7///
8/// ```
9/// use concise_scanf_like_input::read_input_lines;
10/// use std::io::{self, Read, Write};
11/// // you need to make the buffer mutable to allow the macro to fill it
12/// let mut buf = String::new();
13/// // the lines must be mutable to rewind themselves on every new line read
14/// let mut lines: &[&str] = read_input_lines!(buf);
15/// ```
16#[macro_export]
17macro_rules! read_input_lines {
18    ($buf:ident) => {
19	{
20	    let mut stdin = io::stdin();
21	    stdin.read_to_string(&mut $buf);
22	    &$buf.lines().collect::<Vec<_>>()
23	}
24    }
25}
26
27
28/// Reads a sample line from the previously fetched vector of lines, then parses a
29/// heterogeneous sequence of variables and stores them in previously allocated
30/// memory.
31///
32/// # Examples
33///
34/// ```
35/// use concise_scanf_like_input::read_line_of_vars;
36/// let mut lines: &[&str] = &vec!["1", "2 3"];
37/// // you don't need to make a variable mutable
38/// let t: i32;
39/// read_line_of_vars!(i32, lines, t);
40/// for _ in 0..t {
41///	let (n, x): (i32, i32);
42///	read_line_of_vars!(i32, lines, n, x);
43/// }
44/// ```
45#[macro_export]
46macro_rules! read_line_of_vars {
47    ($type:ty, $lines:ident, $($var:ident),+) => {
48	{
49	    let (line, rest) = $lines.split_first().unwrap();
50	    $lines = rest;
51	    let parsed = line.trim().split_whitespace().map(
52		|x| {
53		    x.parse::<$type>().unwrap()
54		}
55	    )
56		.collect::<Vec<$type>>();
57	    let parsed = &parsed[..];
58	    $(
59		match parsed.split_first() {
60		    None => {
61			$var = parsed[0];
62		    },
63		    Some((value, parsed)) => {
64			$var = *value;
65		    }
66		}
67	    );+;
68	    {(
69		$(
70		    $var
71		),+
72	    )}
73	}
74    }
75}