diff --git a/CLI.md b/src/cli/CLI.md similarity index 100% rename from CLI.md rename to src/cli/CLI.md diff --git a/src/cli/help.rs b/src/cli/help.rs new file mode 100644 index 0000000..9668e99 --- /dev/null +++ b/src/cli/help.rs @@ -0,0 +1,7 @@ +use crate::cli::HELP_TEXT; + + +pub fn help_command(options: &Vec) { + println!("{}", HELP_TEXT); +} + diff --git a/src/cli/mod.rs b/src/cli/mod.rs new file mode 100644 index 0000000..ae1f884 --- /dev/null +++ b/src/cli/mod.rs @@ -0,0 +1,86 @@ +mod help; +mod types; + +use types::{Command, CommandType}; + +pub const HELP_TEXT: &str = r#" +Usage: `thp [command] [options]` + +Commands + + c _file_ Compiles `file` in-place + f _file_ Formats `file` + r Starts the REPL + + init Initializes a new project in the current directory + build Builds the project + fmt Formats all files in the project + watch, w Starts compilation of the project in watch mode + + help, h Print this message & exit + +General options + + -h, --help Print command-specific usage +"#; + +fn get_copyright() -> String { + let crate_version = env!("CARGO_PKG_VERSION"); + format!("The THP compiler, linter & formatter, v{}", crate_version) +} + +pub fn run_cli() { + let command = match parse_args() { + Ok(c) => c, + Err(reason) => { + println!("{}", HELP_TEXT); + println!("Error: {}", reason); + return; + }, + }; + + command.run(); +} + +fn parse_args() -> Result { + let mut args = std::env::args().collect::>(); + args.remove(0); + + let mut args = args.into_iter(); + + let command = match args.next() { + Some(command) if !command.starts_with('-') => Some(command), + _ => None, + }; + + let mut options = Vec::new(); + for arg in args { + if arg.starts_with('-') { + options.push(arg); + } else { + return Err(format!( + "Unexpected command `{}` after the options", + arg + )); + } + } + + let command = match command { + Some(command) => match command.as_str() { + "c" | "compile" => CommandType::Compile, + "f" | "format" => CommandType::Format, + "r" | "repl" => CommandType::Repl, + "init" => CommandType::Init, + "build" => CommandType::Build, + "fmt" => CommandType::Fmt, + "watch" | "w" => CommandType::Watch, + "help" | "h" => CommandType::Help, + _ => return Err(format!("Unknown command: {}", command)), + }, + None => CommandType::None, + }; + + Ok(Command { command, options }) +} + + diff --git a/src/cli/types.rs b/src/cli/types.rs new file mode 100644 index 0000000..3d358d6 --- /dev/null +++ b/src/cli/types.rs @@ -0,0 +1,32 @@ +#[derive(Debug)] +pub struct Command { + pub command: CommandType, + pub options: Vec, +} + +#[derive(Debug)] +pub enum CommandType { + Compile, + Format, + Repl, + Init, + Build, + Fmt, + Watch, + Help, + None, +} + + +impl Command { + pub fn run(&self) { + println!("Running command! {:?}", self); + self.command.run(&self.options); + } +} + +impl CommandType { + pub fn run(&self, options: &Vec) { + println!("Running command! {:?}", self) + } +} diff --git a/src/main.rs b/src/main.rs index a51c0b3..534b938 100755 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,5 @@ +// Module to handle the CLI +mod cli; // Module to handle the repl and its compilation mod repl; @@ -13,12 +15,6 @@ mod utils; mod error_handling; -fn get_copyright() -> String { - let crate_version = env!("CARGO_PKG_VERSION"); - format!("The THP compiler, linter & formatter, v{}", crate_version,) -} - fn main() { - println!("{}", get_copyright()); - println!("Rewriting CLI..."); + cli::run_cli(); }