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<Cmd>,
pub download: bool,
pub update: bool,
pub mod_options: Option<ModOptions>,
pub mod_id: Option<String>,
pub mod_version: Option<String>,
pub list: Option<List>,
pub list_options: Option<ListOptions>,
pub list_id: Option<String>,
pub list_mcversion: Option<String>,
pub modloader: Option<Modloader>,
pub directory: Option<String>,
pub export: bool,
pub import: bool,
pub file: Option<String>,
}
#[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,
}
impl Input {
fn from(config: Cfg, input: Vec<String>) -> MLE<Self> {
let input_string = input.join(" ");
let mut args: Vec<&str> = input_string.split('-').collect();
args.reverse();
args.pop();
args.reverse();
let mut command: Option<Cmd> = None;
let mut download = false;
let mut update = false;
let mut mod_options: Option<ModOptions> = None;
let mut mod_id: Option<String> = None;
let mut mod_version: Option<String> = None;
let mut list: Option<List> = None;
let mut list_options: Option<ListOptions> = None;
let mut list_id: Option<String> = None;
let mut list_mcversion: Option<String> = None;
let mut modloader: Option<Modloader> = None;
let mut directory: Option<String> = None;
let mut export = false;
let mut import = false;
let mut file: Option<String> = 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);
mod_id = Some(String::from(arg_split[1]));
},
"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]));
}
_ => return Err(MLError::new(ErrorType::ArgumentError, "UnknownArgument")),
}
}
Ok(Self {
command,
download,
update,
mod_options,
mod_id,
mod_version,
list,
list_options,
list_id,
list_mcversion,
modloader,
directory,
export,
import,
file
})
}
}
fn show_version() {
match std::env::var("DEV") {
Ok(dev) => {
let devint = dev.parse::<i32>().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<String>) -> MLE<Input> {
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),
}
}
fn check_mod(mut input: Input, config: Cfg) -> MLE<Input> {
print!("Checkmod");
if input.mod_options.is_none() {
return Err(MLError::new(ErrorType::ArgumentError, "NO_MOD_ARGUMENT"));
};
match input.clone().mod_options.unwrap() {
ModOptions::Add => {
print!("Checkadd");
if input.mod_id.is_none() { return Err(MLError::new(ErrorType::ArgumentError, "MODS_NO_MODID")); };
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() { return Err(MLError::new(ErrorType::ArgumentError, "MODS_NO_MODID")); };
Ok(input)
},
}
}
fn check_list(mut input: Input) -> MLE<Input> {
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<Input> {
Ok(input)
}
fn check_download(input: Input) -> MLE<Input> {
Ok(input)
}
fn check_io(input: Input) -> MLE<Input> {
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),
download: false,
update: false,
mod_options: None,
mod_id: None,
mod_version: None,
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,
export: false,
import: false,
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),
download: false,
update: false,
mod_options: Some(ModOptions::Add),
mod_id: Some(String::from("test")),
mod_version: None,
list: Some(lists_get(config.clone(), String::from("one")).unwrap()),
list_options: None,
list_id: None,
list_mcversion: None,
modloader: None,
directory: None,
export: false,
import: false,
file: None
}
)
}