aboutsummaryrefslogtreecommitdiff
path: root/crates/cli/src
diff options
context:
space:
mode:
Diffstat (limited to 'crates/cli/src')
-rw-r--r--crates/cli/src/init.rs55
-rw-r--r--crates/cli/src/main.rs81
-rw-r--r--crates/cli/src/nuke.rs36
-rw-r--r--crates/cli/src/run.rs3
-rw-r--r--crates/cli/src/words.rs141
5 files changed, 316 insertions, 0 deletions
diff --git a/crates/cli/src/init.rs b/crates/cli/src/init.rs
new file mode 100644
index 0000000..7de2e8c
--- /dev/null
+++ b/crates/cli/src/init.rs
@@ -0,0 +1,55 @@
+fn help() {
+ println!("mihi init: Initialize 'mihi' for a given language.\n");
+ println!("usage: mihi init [OPTIONS]\n");
+
+ println!("Options:");
+ println!(" -h, --help\t\tPrint this message.");
+ println!(" -l, --language\tThe language to be used.");
+}
+
+pub fn run(args: Vec<String>) {
+ let mut given_language: Option<String> = None;
+ let mut it = args.into_iter();
+
+ while let Some(arg) = it.next() {
+ match arg.as_str() {
+ "-h" | "--help" => {
+ help();
+ std::process::exit(0);
+ }
+ "-l" | "--language" => match it.next() {
+ Some(lang) => given_language = Some(lang),
+ None => {
+ println!(
+ "error: init: you have to provide a value for the '-l/--language' flag"
+ );
+ std::process::exit(1);
+ }
+ },
+ _ => {
+ println!("error: init: unknown flag: '{}'", arg.as_str());
+ std::process::exit(1);
+ }
+ }
+ }
+
+ // Assume latin for now. If we support more languages in the future, there
+ // should be a prompt or something.
+ let language = match given_language {
+ Some(lang) => lang,
+ None => String::from("latin"),
+ };
+
+ match init(language) {
+ Ok(_) => {}
+ Err(e) => {
+ println!("error: init: {}", e);
+ std::process::exit(1);
+ }
+ }
+}
+
+fn init(language: String) -> Result<(), String> {
+ mihi::add_language(language)?;
+ mihi::init_database()
+}
diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs
new file mode 100644
index 0000000..78d094d
--- /dev/null
+++ b/crates/cli/src/main.rs
@@ -0,0 +1,81 @@
+mod init;
+mod nuke;
+mod run;
+mod words;
+
+/// Version for this program.
+const VERSION: &str = "0.1.0";
+
+fn help() {
+ println!("Self-assessment tool for language learning.\n");
+ println!("usage: mihi [OPTIONS] [COMMAND] [COMMAND OPTIONS]\n");
+
+ println!("Options:");
+ println!(" -h, --help\t\tPrint this message.");
+ println!(" -v, --version\tPrint the version of this program.\n");
+
+ println!("Commands:");
+ println!(" init\t\t\tInitialize the configuration for this application.");
+ println!(" nuke\t\t\tRemove all files from this application and its database.");
+ println!(" run\t\t\tRun exercises. Default command if none was given.");
+ println!(" words\t\tManage the words for this application.");
+}
+
+fn main() {
+ let mut args = std::env::args();
+ let nargs = std::env::args().count();
+ let mut count = 1;
+
+ // Skip command name.
+ args.next();
+
+ // And iterate over the arguments.
+ while let Some(arg) = args.next() {
+ count += 1;
+
+ match arg.as_str() {
+ "-h" | "--help" => {
+ if nargs > count {
+ println!(
+ "warning: arguments passed the '{}' flag will be ignored.",
+ arg.as_str()
+ );
+ }
+ help();
+ std::process::exit(0);
+ }
+ "-v" | "--version" => {
+ if nargs > count {
+ println!(
+ "warning: arguments passed the '{}' flag will be ignored.",
+ arg.as_str()
+ );
+ }
+ println!("mihi {}", VERSION);
+ std::process::exit(0);
+ }
+ "init" => {
+ let rest: Vec<String> = args.collect();
+ return init::run(rest);
+ }
+ "nuke" => {
+ let rest: Vec<String> = args.collect();
+ return nuke::run(rest);
+ }
+ "words" => {
+ let rest: Vec<String> = args.collect();
+ return words::run(rest);
+ }
+ "run" => {
+ let rest: Vec<String> = args.collect();
+ return run::run(rest);
+ }
+ _ => {
+ println!("error: unknown flag or command: '{}'", arg.as_str());
+ std::process::exit(1);
+ }
+ }
+ }
+
+ run::run(Vec::new());
+}
diff --git a/crates/cli/src/nuke.rs b/crates/cli/src/nuke.rs
new file mode 100644
index 0000000..1ea6532
--- /dev/null
+++ b/crates/cli/src/nuke.rs
@@ -0,0 +1,36 @@
+fn help() {
+ println!("mihi nuke: Nuke the current installation.\n");
+ println!("usage: mihi nuke [OPTIONS]\n");
+
+ println!("Options:");
+ println!(" -h, --help\t\tPrint this message.");
+}
+
+pub fn run(args: Vec<String>) {
+ for arg in args {
+ match arg.as_str() {
+ "-h" | "--help" => {
+ help();
+ std::process::exit(0);
+ }
+ _ => {
+ println!("error: nuke: unknown flag: '{}'", arg.as_str());
+ std::process::exit(1);
+ }
+ }
+ }
+
+ match mihi::get_config_path() {
+ Ok(path) => match std::fs::remove_dir_all(path) {
+ Ok(_) => {}
+ Err(e) => {
+ println!("error: nuke: {}", e);
+ std::process::exit(1);
+ }
+ },
+ Err(e) => {
+ println!("error: nuke: {}", e);
+ std::process::exit(1);
+ }
+ }
+}
diff --git a/crates/cli/src/run.rs b/crates/cli/src/run.rs
new file mode 100644
index 0000000..2288a17
--- /dev/null
+++ b/crates/cli/src/run.rs
@@ -0,0 +1,3 @@
+pub fn run(args: Vec<String>) {
+ println!("TBD: {:#?}", args);
+}
diff --git a/crates/cli/src/words.rs b/crates/cli/src/words.rs
new file mode 100644
index 0000000..bdf49b5
--- /dev/null
+++ b/crates/cli/src/words.rs
@@ -0,0 +1,141 @@
+use inquire::{Confirm, Select};
+use std::vec::IntoIter;
+
+use mihi::{delete_word, select_enunciated};
+
+fn help() {
+ println!("mihi words: Manage words.\n");
+ println!("usage: mihi words [OPTIONS] <subcommand>\n");
+
+ println!("Options:");
+ println!(" -h, --help\t\tPrint this message.");
+
+ println!("\nSubcommands:");
+ println!(" create\t\tCreate a new word.");
+ println!(" ls\t\t\tList the words from the database.");
+ println!(" rm\t\t\tRemove a word from the database.");
+ println!(" show\t\t\tShow information from a word.");
+}
+
+fn create(args: IntoIter<String>) -> i32 {
+ println!("TBD: {:#?}", args);
+
+ return 0;
+}
+
+fn show(args: IntoIter<String>) -> i32 {
+ println!("TBD: {:#?}", args);
+
+ return 0;
+}
+
+fn ls(mut args: IntoIter<String>) -> i32 {
+ if args.len() > 1 {
+ println!("error: words: too many filters");
+ return 1;
+ }
+
+ let words = match select_enunciated(args.next()) {
+ Ok(words) => words,
+ Err(e) => {
+ println!("error: words: {}", e);
+ return 1;
+ }
+ };
+
+ for enunciated in words {
+ println!("{}", enunciated);
+ }
+
+ return 0;
+}
+
+fn rm(mut args: IntoIter<String>) -> i32 {
+ if args.len() > 1 {
+ println!("error: words: too many filters");
+ return 1;
+ }
+
+ let words = match select_enunciated(args.next()) {
+ Ok(words) => words,
+ Err(e) => {
+ println!("error: words: {}", e);
+ return 1;
+ }
+ };
+
+ let selection: String = match words.len() {
+ 0 => {
+ println!("errors: words: not found!");
+ return 1;
+ }
+ 1 => words.first().unwrap().to_owned(),
+ _ => match Select::new("Which word?", words).prompt() {
+ Ok(choice) => choice,
+ Err(_) => return 1,
+ },
+ };
+
+ let ans = Confirm::new(
+ format!(
+ "Do you really want to remove '{}' from the database?",
+ selection
+ )
+ .as_str(),
+ )
+ .with_default(true)
+ .prompt();
+
+ match ans {
+ Ok(true) => match delete_word(&selection) {
+ Ok(_) => println!("Removed '{}' from the database!", selection),
+ Err(e) => {
+ println!("error: words: {}", e);
+ return 1;
+ }
+ },
+ Ok(false) => {
+ println!("Doing nothing...");
+ }
+ Err(_) => return 1,
+ }
+
+ return 0;
+}
+
+pub fn run(args: Vec<String>) {
+ if args.is_empty() {
+ println!("error: words: you have to provide at least a subcommand");
+ std::process::exit(1);
+ }
+
+ let mut it = args.into_iter();
+
+ while let Some(first) = it.next() {
+ match first.as_str() {
+ "-h" | "--help" => {
+ help();
+ std::process::exit(0);
+ }
+ "create" => {
+ std::process::exit(create(it));
+ }
+ "ls" => {
+ std::process::exit(ls(it));
+ }
+ "rm" => {
+ std::process::exit(rm(it));
+ }
+ "show" => {
+ std::process::exit(show(it));
+ }
+ _ => {
+ println!(
+ "error: words: unknown flag or command: '{}'",
+ first.as_str()
+ );
+ std::process::exit(1);
+ }
+ }
+ }
+}