use std::{io::IsTerminal, path::PathBuf, str::FromStr};
argwerk::define! {
#[usage = "conlang [<file>] [-I <include...>] [-m <mode>] [-r <repl>]"]
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct Args {
pub file: Option<PathBuf>,
pub include: Vec<PathBuf>,
pub mode: Mode,
pub repl: bool = is_terminal(),
}
["-I" | "--include", path] => {
include.push(path.into());
}
["-m" | "--mode", flr] => {
mode = flr.parse()?;
}
["-r" | "--repl", bool] => {
repl = bool.parse()?;
}
["-h" | "--help"] => {
println!("{}", Args::help());
if true { std::process::exit(0); }
}
[#[option] path] if file.is_none() => {
file = path.map(Into::into);
}
}
pub fn is_terminal() -> bool {
std::io::stdin().is_terminal() && std::io::stdout().is_terminal()
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
pub enum Mode {
#[default]
Menu,
Lex,
Fmt,
Run,
}
impl FromStr for Mode {
type Err = &'static str;
fn from_str(s: &str) -> Result<Self, &'static str> {
Ok(match s {
"f" | "fmt" | "p" | "pretty" => Mode::Fmt,
"l" | "lex" | "tokenize" | "token" => Mode::Lex,
"r" | "run" => Mode::Run,
_ => Err("Recognized modes are: 'r' \"run\", 'f' \"fmt\", 'l' \"lex\"")?,
})
}
}