use std::io;
use std::str::FromStr;
pub type ParseResult<T> = Result<T, <T as FromStr>::Err>;
pub type ParseFunction<T> = Box<dyn Fn(&str) -> ParseResult<T>>;
pub type Closures<T> = Vec<ParseFunction<T>>;
pub fn _fmtin<T: FromStr>(sep: &str, fmt_funs: Closures<T>, mut vals: Vec<&mut T>) {
let stdin = io::stdin();
let mut input = String::new();
let _ = stdin.read_line(&mut input).unwrap();
let parts: Vec<&str> = input.split(sep).collect();
if fmt_funs.len() != vals.len() || fmt_funs.len() != parts.len() {
panic!();
}
for ((fun, part), val) in fmt_funs.into_iter().zip(parts.iter()).zip(vals.iter_mut()) {
match (fun)(part) {
Ok(parsed_value) => **val = parsed_value,
Err(_) => panic!(),
}
}
}
pub fn pf<T: FromStr>() -> ParseFunction<T> {
Box::new(|s: &str| s.to_string().parse::<T>())
}
#[macro_export]
macro_rules! fmtin {
($( $n:ident : $t:ty ),* ; sep = $sep:expr) => {
{
let mut fs = Vec::new();
let mut vs = Vec::new();
$(
fs.push(pf::<$t>());
vs.push(&mut $n);
)*
_fmtin($sep, fs, vs)
}
};
($( $n:ident : $t:ty ),*) => {
fmtin!($( $n : $t ),*; sep = " ")
};
}