use crate::{error::{MLE, MLError, ErrorType}, Modloader, config::Cfg, db::lists_get, get_current_list, List}; #[derive(Debug, Clone, PartialEq, Eq)] pub struct Input { pub command: Option, pub mod_options: Option, pub mod_id: Option, pub mod_version: Option, pub set_version: bool, pub list: Option, pub list_options: Option, pub list_id: Option, pub list_mcversion: Option, pub modloader: Option, pub directory: Option, pub io_options: Option, pub file: Option, } #[derive(Debug, Clone, PartialEq, Eq)] pub enum Cmd { Mod, List, Update, Download, Io, } #[derive(Debug, Clone, PartialEq, Eq)] pub enum ModOptions { Add, Remove } #[derive(Debug, Clone, PartialEq, Eq)] pub enum ListOptions { Add, Remove, Change, } #[derive(Debug, Clone, PartialEq, Eq)] pub enum IoOptions { Export, Import } impl Input { fn from(config: Cfg, input: Vec) -> MLE { let input_string = input.join(" "); let mut args: Vec<&str> = input_string.split('-').collect(); args.reverse(); args.pop(); args.reverse(); let mut command: Option = None; let mut mod_options: Option = None; let mut mod_id: Option = None; let mut mod_version: Option = None; let mut set_version = false; let mut list: Option = None; let mut list_options: Option = None; let mut list_id: Option = None; let mut list_mcversion: Option = None; let mut modloader: Option = None; let mut directory: Option = None; let mut io_options: Option = None; let mut file: Option = None; for arg in args { let arg_split: Vec<&str> = arg.trim().split(" ").collect(); match arg_split[0] { "v" | "version" => { show_version(); }, "d" | "download" => { command = Some(Cmd::Download); }, "u" | "update" => { command = Some(Cmd::Update); }, "ma" => { command = Some(Cmd::Mod); mod_options = Some(ModOptions::Add); if arg_split.len() != 1 { mod_id = Some(String::from(arg_split[1])); } }, "mr" => { command = Some(Cmd::Mod); mod_options = Some(ModOptions::Remove); if arg_split.len() != 1 { mod_id = Some(String::from(arg_split[1])); } }, "mv" => { if arg_split.len() != 1 { mod_version = Some(String::from(arg_split[1])); }; }, "set-version" => { set_version = true; }, "l" => { list = Some(lists_get(config.clone(), String::from(arg_split[1]))?); } "la" => { command = Some(Cmd::List); list_options = Some(ListOptions::Add); list_id = Some(String::from(arg_split[1])); }, "lr" => { command = Some(Cmd::List); list_options = Some(ListOptions::Remove); list_id = Some(String::from(arg_split[1])); }, "lc" => { command = Some(Cmd::List); list_options = Some(ListOptions::Change); list_id = Some(String::from(arg_split[1])); }, "lv" => { list_mcversion = Some(String::from(arg_split[1])); }, "ml" => { modloader = Some(Modloader::from(arg_split[1])?); }, "dir" => { directory = Some(String::from(arg_split[1])); }, "export" => { command = Some(Cmd::Io); io_options = Some(IoOptions::Export); }, "import" => { command = Some(Cmd::Io); io_options = Some(IoOptions::Import); }, "f" => { file = Some(String::from(arg_split[1])); }, _ => return Err(MLError::new(ErrorType::ArgumentError, "UnknownArgument")), } } Ok(Self { command, mod_options, mod_id, mod_version, set_version, list, list_options, list_id, list_mcversion, modloader, directory, io_options, file }) } } fn show_version() { match std::env::var("DEV") { Ok(dev) => { let devint = dev.parse::().unwrap(); if devint >= 1 { println!("Modlist by FxQnLr v{} (DEV)", env!("CARGO_PKG_VERSION")); } else { println!("Modlist by FxQnLr v{}", env!("CARGO_PKG_VERSION")); } }, Err(..) => println!("Modlist by FxQnLr v{}", env!("CARGO_PKG_VERSION")), } std::process::exit(0); } pub async fn get_input(config: Cfg, args: Vec) -> MLE { let input = Input::from(config.clone(), args)?; match input.clone().command.unwrap() { Cmd::Mod => check_mod(input, config), Cmd::List => check_list(input), Cmd::Update => check_update(input), Cmd::Download => check_download(input), Cmd::Io => check_io(input), } } //Move checks to commands? translate to variables there? fn check_mod(mut input: Input, config: Cfg) -> MLE { if input.mod_options.is_none() { return Err(MLError::new(ErrorType::ArgumentError, "NO_MOD_ARGUMENT")); }; match input.clone().mod_options.unwrap() { //Check for MV if no mod-id on both ModOptions::Add => { if input.mod_id.is_none() && input.mod_version.is_none() { return Err(MLError::new(ErrorType::ArgumentError, "MODS_NO_MODID_MODVERSION")); }; if input.list_id.is_none() { println!("NOLIST"); input.list = Some(get_current_list(config.clone())?); }; Ok(input) }, ModOptions::Remove => { if input.mod_id.is_none() && input.mod_version.is_none() { return Err(MLError::new(ErrorType::ArgumentError, "MODS_NO_MODID_MODVERSION")); }; Ok(input) }, } } fn check_list(mut input: Input) -> MLE { if input.list_options.is_none() { return Err(MLError::new(ErrorType::ArgumentError, "NO_LIST_ARGUMENT")); }; match input.clone().list_options.unwrap() { ListOptions::Add => { if input.list_id.is_none() { return Err(MLError::new(ErrorType::ArgumentError, "LISTS_NO_ID")); }; if input.list_mcversion.is_none() { /*TODO Get latest version */ input.list_mcversion = Some(String::from("1.19.3")) }; if input.modloader.is_none() { return Err(MLError::new(ErrorType::ArgumentError, "LISTS_NO_MODLOADER")); }; if input.directory.is_none() { input.directory = Some(format!("./downloads/{}", input.clone().list_id.expect("earlier if failed"))) }; Ok(input) }, ListOptions::Remove => { if input.list_id.is_none() { return Err(MLError::new(ErrorType::ArgumentError, "LISTS_NO_ID")); }; Ok(input) }, ListOptions::Change => { //TODO check if no change if input.list_id.is_none() { return Err(MLError::new(ErrorType::ArgumentError, "LISTS_NO_ID")); }; Ok(input) } } } fn check_update(input: Input) -> MLE { Ok(input) } fn check_download(input: Input) -> MLE { Ok(input) } fn check_io(input: Input) -> MLE { Ok(input) } #[test] fn input_from() { let config = Cfg::init("modlist.toml").unwrap(); assert_eq!( Input::from(config.clone(), vec![String::from("-la test -lv 1.19.3")]).unwrap(), Input { command: Some(Cmd::List), mod_options: None, mod_id: None, mod_version: None, set_version: false, list: None, list_options: Some(ListOptions::Add), list_id: Some(String::from("test")), list_mcversion: Some(String::from("1.19.3")), modloader: None, directory: None, io_options: None, file: None } ); } #[tokio::test] async fn get_input_test() { let config = Cfg::init("modlist.toml").unwrap(); assert_eq!( get_input(config.clone(), vec![String::from("-ma test")]).await.unwrap(), Input { command: Some(Cmd::Mod), mod_options: Some(ModOptions::Add), mod_id: Some(String::from("test")), mod_version: None, set_version: false, list: Some(lists_get(config.clone(), String::from("one")).unwrap()), list_options: None, list_id: None, list_mcversion: None, modloader: None, directory: None, io_options: None, file: None } ) }