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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#[macro_export]
macro_rules! read(
() => { read!("{}") };
($text:expr) => {{
let value;
scan!($text, value);
value
}};
($text:expr, $input:expr) => {{
let value;
scan!($input => $text, value);
value
}};
);
#[macro_export]
macro_rules! scan(
($text:expr, $($arg:ident),*) => { scan!(std::io::stdin().bytes().map(|c| c.unwrap()) => $text, $($arg),*) };
($input:expr => $text:expr, $($arg:ident),*) => {{
use std::io::Read;
use std::str::FromStr;
let text: &'static str = $text;
let stdin: &mut Iterator<Item = u8> = &mut ($input);
let mut text = text.bytes();
$(
loop { match text.next() {
Some(b'{') => match text.next() {
Some(b'{') => assert_eq!(Some(b'{'), stdin.next()),
Some(b'}') => {
let s: Vec<u8> = match text.next() {
Some(c) => stdin.take_while(|&ch| ch != c).collect(),
None => stdin.take_while(|ch| !b"\t\r\n ".contains(ch)).collect(),
};
let s = match std::str::from_utf8(&s) {
Ok(s) => s,
Err(e) => {
let n = e.valid_up_to();
if n == 0 {
panic!("input was not valid utf8: {:?}", s);
} else {
panic!("input was only partially valid utf8: \"{}\" followed by {:?}",
std::str::from_utf8(&s[..n]).unwrap(), &s[n..]);
}
}
};
$arg = FromStr::from_str(s).expect(&format!("could not parse {} as target type of {}", s, stringify!($arg)));
break;
}
Some(_) => panic!("found bad curly brace"),
None => panic!("found single open curly brace at the end of the format string"),
},
Some(c) => assert_eq!(Some(c), stdin.next()),
None => panic!("Bad read! format string: did not contain {{}}"),
} }
)*
for c in text {
assert_eq!(Some(c), stdin.next());
}
}};
);