use std::{
env::args,
path::PathBuf,
};
use crate::Error;
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Subcommand {
Repl,
Run,
Latex,
Help,
Version,
}
impl From<&str> for Subcommand {
fn from(input: &str) -> Self {
use Subcommand::*;
match input {
"repl" => Repl,
"run" => Run,
"latex" => Latex,
"help" => Help,
"version" => Version,
_ => Error::UnrecognizedSubcommand (input).throw(),
}
}
}
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub enum Flag {
Debug,
Interactive,
}
impl From<&str> for Flag {
fn from(input: &str) -> Self {
use Flag::*;
match input {
"debug" => Debug,
"interactive" => Interactive,
_ => Error::UnrecognizedFlag (input).throw(),
}
}
}
impl From<char> for Flag {
fn from(input: char) -> Self {
use Flag::*;
match input {
'd' => Debug,
'i' => Interactive,
_ => Error::UnrecognizedFlag (input).throw(),
}
}
}
pub struct CliArgs {
pub subcommand: Subcommand,
pub argument: Option<String>,
pub inputfile: Option<PathBuf>,
pub flags: Vec<Flag>,
}
impl CliArgs {
pub fn parse() -> Self {
let args = args().collect::<Vec<String>>();
let subcommand = if args.len() > 1 {
args[1].as_str().into()
} else {
Subcommand::Repl
};
let mut argument: Option<String> = None;
let mut inputfile: Option<PathBuf> = None;
if subcommand == Subcommand::Help && args.len() > 2 && !args[2].starts_with("-") {
argument = Some (args[2].to_owned());
} else if subcommand != Subcommand::Help && args.len() > 2 && !args[2].starts_with("-") {
inputfile = Some (args[2].as_str().into());
}
let mut flags = Vec::new();
let mut i = if let Some (_) = &inputfile {
3
} else if let Some(_) = &argument {
3
} else {
2
};
while i < args.len() {
let arg = &args[i];
if arg.starts_with("--") {
flags.push(arg[2..].into());
} else if arg.starts_with("-") {
for c in arg[1..].chars() {
flags.push(c.into());
}
} else {
Error::UnrecognizedArgument (arg).throw();
}
i += 1;
}
Self {
subcommand,
argument,
inputfile,
flags,
}
}
pub fn contains(&self, flag: Flag) -> bool {
for f in &self.flags {
if *f == flag {
return true;
}
}
return false;
}
}