use crate::{modrinth::{project, versions, extract_current_version, Version, projects}, config::Cfg, db::{mods_insert, userlist_remove, mods_get_id, userlist_insert, userlist_get_all_ids, userlist_get_current_version, lists_get_all_ids, mods_remove}, input::{Input, ModOptions}, files::{delete_version, download_versions}, List, error::{MLE, ErrorType, MLError}}; //TODO DO IT pub struct ModVer { } pub async fn modification(config: Cfg, input: Input) -> MLE<()> { match input.clone().mod_options.ok_or("").unwrap() { ModOptions::Add => { add(config, input).await }, ModOptions::Remove => { remove(config, input) }, } } async fn add(config: Cfg, input: Input) -> MLE<()> { mods_add(config, vec![input.mod_id.unwrap()], input.list.unwrap(), input.direct_download, input.set_version).await?; Ok(()) } //TODO impl specific version pub async fn mods_add(config: Cfg, mod_id: Vec, list: List, direct_download: bool, set_version: bool) -> MLE<()> { println!("Add mods to {}", list.id); println!(" └Add mods:"); let projects = if mod_id.len() == 1 { vec![project(String::from(&config.apis.modrinth), &mod_id[0]).await] } else { projects(String::from(&config.apis.modrinth), mod_id).await }; let mut downloadstack: Vec = Vec::new(); for project in projects { println!("\t└{}", project.title); println!("\t └Get versions"); let available_versions = versions(String::from(&config.apis.modrinth), String::from(&project.id), list.clone()).await; let mut available_versions_vec: Vec = Vec::new(); let current_version: Option; let current_version_id: String; let file: String; if !available_versions.is_empty() { let current_id = extract_current_version(available_versions.clone())?; println!("\t └Current version: {}", current_id); current_version = Some(available_versions.clone().into_iter().find(|v| v.id == current_id).unwrap()); current_version_id = current_version.clone().unwrap().id; file = current_version.clone().ok_or("").unwrap().files.into_iter().find(|f| f.primary).unwrap().url; for ver in available_versions { available_versions_vec.push(ver.id); }; } else { println!("\t └There's currently no mod version for your specified target"); current_version = None; current_version_id = String::from("NONE"); file = String::from("NONE"); available_versions_vec.push(String::from("NONE")); } match userlist_insert(config.clone(), &list.id, &project.id, ¤t_version_id, available_versions_vec, &file, set_version) { Err(e) => { let expected_err = format!("SQL: UNIQUE constraint failed: {}.mod_id", list.id); if e.to_string() == expected_err { Err(MLError::new(ErrorType::ModError, "MOD_ALREADY_ON_SELECTED_LIST")) } else { Err(e) } }, Ok(..) => { Ok(..) }, }?; match mods_insert(config.clone(), &project.id, &project.slug, &project.title) { Err(e) => { if e.to_string() == "SQL: UNIQUE constraint failed: mods.id" { Ok(..) } else { Err(e) } }, Ok(..) => Ok(..), }?; downloadstack.push(current_version.unwrap()); }; //Download all the added mods if direct_download { download_versions(list.clone(), config.clone(), downloadstack).await?; }; Ok(()) } fn remove(config: Cfg, input: Input) -> MLE<()> { let mod_id = mods_get_id(&config.data, input.mod_id.as_ref().unwrap())?; let version = userlist_get_current_version(config.clone(), input.clone().list.unwrap().id, String::from(&mod_id))?; userlist_remove(config.clone(), input.clone().list.unwrap().id, String::from(&mod_id))?; delete_version(input.list.unwrap(), version)?; let list_ids = lists_get_all_ids(config.clone())?; let mut mod_used = false; for id in list_ids { let mods = userlist_get_all_ids(config.clone(), id)?; if mods.contains(&mod_id) { mod_used = true; break; }; }; if !mod_used { mods_remove(config, mod_id)?; }; Ok(()) }