pub mod input_options;
pub mod ranges;
use std::{error::Error, io::Write};
pub type BoxResult<T> = Result<T, Box<dyn Error>>;
#[macro_export]
macro_rules! read {
($($args:tt)*) => {
smart_read::try_read!($($args)*).unwrap()
}
}
#[macro_export]
macro_rules! try_read {
() => {
smart_read::read_string()
};
($input:expr) => {{
use smart_read::ReadLine;
$input.try_read_line()
}};
(= $($input:expr),*) => {{
use smart_read::ReadLine;
let mut choices = vec!();
$(choices.push($input);)*
choices.try_read_line()
}};
}
#[macro_export]
macro_rules! prompt {
($($args:tt)*) => {
smart_read::try_prompt!($($args)*).unwrap()
}
}
#[macro_export]
macro_rules! try_prompt {
($prompt:expr) => {{
print!("{}", $prompt);
smart_read::read_string()
}};
($prompt:expr; $input:expr) => {{
use smart_read::ReadLine;
println!("{}", $prompt);
$input.try_read_line()
}};
($prompt:expr; = $($input:expr),*) => {{
use smart_read::ReadLine;
let mut choices = vec!();
$(choices.push($input);)*
println!("{}", $prompt);
choices.try_read_line()
}};
}
pub trait ReadLine {
type Output;
fn try_read_line(&self) -> BoxResult<Self::Output>;
fn read_line(&self) -> Self::Output {
self.try_read_line().unwrap()
}
}
pub fn read_string() -> BoxResult<String> {
let mut output = String::new();
std::io::stdout().flush()?;
std::io::stdin().read_line(&mut output)?;
if output.as_bytes().last() == Some(&10) {output.pop();} if output.as_bytes().last() == Some(&13) {output.pop();} Ok(output)
}