Skip to content

Instantly share code, notes, and snippets.

@BusyJay
Last active September 17, 2016 17:07
Show Gist options
  • Save BusyJay/f8253f8896411a9d9c86392679426e39 to your computer and use it in GitHub Desktop.
Save BusyJay/f8253f8896411a9d9c86392679426e39 to your computer and use it in GitHub Desktop.
Rust stdin helper snippets for ojer
use std::io::{self, BufReader, Read, Stdin, Bytes};
use std::fmt::Debug;
use std::str::FromStr;
/// A stdin helper to deal with normal oj input.
pub struct OjReader<R> {
bs: Bytes<BufReader<R>>,
}
pub fn from_stdin() -> OjReader<Stdin> {
let input = io::stdin();
let reader = BufReader::new(input);
OjReader { bs: reader.bytes() }
}
impl<R: Read> OjReader<R> {
pub fn next<E, T>(&mut self) -> T
where E: Debug,
T: FromStr<Err = E>
{
loop {
match self.next_opt() {
Some(t) => return t,
None => {},
}
}
}
pub fn next_opt<E, T>(&mut self) -> Option<T>
where E: Debug,
T: FromStr<Err = E>
{
self.next_trunk(|b| b == b' ' || b == b'\t' || b == b'\n' || b == b'\r')
}
// TODO: handle windows style line seperator \r\n
fn next_trunk<E, T, F>(&mut self, is_sep: F) -> Option<T>
where E: Debug,
T: FromStr<Err = E>,
F: Fn(u8) -> bool
{
let mut res = vec![];
loop {
match self.bs.next() {
None => {
assert!(!res.is_empty());
break;
},
Some(r) => {
let b = r.unwrap();
if is_sep(b) {
break;
}
res.push(b);
}
}
}
if res.is_empty() {
return None;
}
unsafe { Some(String::from_utf8_unchecked(res).parse::<T>().unwrap()) }
}
pub fn next_line(&mut self) -> String {
self.next_line_opt().unwrap()
}
pub fn next_line_opt(&mut self) -> Option<String> {
self.next_trunk(|b| b == b'\n' || b == b'\r')
}
}
// Simple a + b example
fn main() {
let mut reader = from_stdin();
let (a, b): (i64, i64) = (reader.next(), reader.next());
println!("{}", a + b);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment