forked from EbTech/rust-algorithms
-
Notifications
You must be signed in to change notification settings - Fork 0
/
scanner.rs
65 lines (57 loc) · 1.66 KB
/
scanner.rs
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
//! Generic utility for reading data from standard input, based on [voxl's
//! stdin wrapper](http://codeforces.com/contest/702/submission/19589375).
use std::io;
/// Reads white-space separated tokens one at a time.
pub struct Scanner<B> {
reader: B,
buffer: Vec<String>,
}
impl<B: io::BufRead> Scanner<B> {
pub fn new(reader: B) -> Self {
Self {
reader: reader,
buffer: Vec::new(),
}
}
/// Use "turbofish" syntax next::<T>() to select data type of next token.
pub fn next<T: ::std::str::FromStr>(&mut self) -> T
where
T::Err: ::std::fmt::Debug,
{
if let Some(front) = self.buffer.pop() {
front.parse::<T>().expect(&front)
} else {
let mut input = String::new();
self.reader.read_line(&mut input).expect("Line not read");
self.buffer = input.split_whitespace().rev().map(String::from).collect();
self.next()
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_fake_input() {
let cursor = io::Cursor::new("44 2");
let mut scan = Scanner::new(cursor);
let x = scan.next::<i32>();
let y = scan.next::<i32>();
assert_eq!(x - y, 42);
}
#[test]
fn test_stdin() {
let stdin = io::stdin();
let mut scan = Scanner::new(stdin.lock());
if false {
let _ = scan.next::<i32>();
}
}
#[test]
#[should_panic]
fn test_file() {
let file = ::std::fs::File::open("asdf.txt").expect("File not found");
let mut scan = Scanner::new(io::BufReader::new(file));
let _ = scan.next::<i32>();
}
}