diff options
Diffstat (limited to 'crates')
| -rw-r--r-- | crates/cli/Cargo.toml | 13 | ||||
| -rw-r--r-- | crates/cli/src/init.rs | 55 | ||||
| -rw-r--r-- | crates/cli/src/main.rs | 81 | ||||
| -rw-r--r-- | crates/cli/src/nuke.rs | 36 | ||||
| -rw-r--r-- | crates/cli/src/run.rs | 3 | ||||
| -rw-r--r-- | crates/cli/src/words.rs | 141 |
6 files changed, 329 insertions, 0 deletions
diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml new file mode 100644 index 0000000..b35c369 --- /dev/null +++ b/crates/cli/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "cli" +version = "0.1.0" +edition = "2021" +authors = ["Miquel Sabaté Solà <mikisabate@gmail.com>"] + +[[bin]] +name = "mihi" +path = "src/main.rs" + +[dependencies] +mihi.workspace = true +inquire = "0.7.5" 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); + } + } + } +} |
