From 9c984cef9a2d0fb223635617934959480e8ca2df Mon Sep 17 00:00:00 2001 From: fxqnlr Date: Sun, 19 Feb 2023 11:49:23 +0100 Subject: Added adding of specific mod-version --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/apis/modrinth.rs | 16 ++-- src/commands/download.rs | 2 +- src/commands/io.rs | 4 +- src/commands/modification.rs | 211 ++++++++++++++++++++++++++++++++++--------- src/commands/update.rs | 8 +- src/db.rs | 22 +++-- src/files.rs | 6 +- src/input.rs | 25 +++-- 10 files changed, 215 insertions(+), 83 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e1b7443..2fe01ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -624,7 +624,7 @@ dependencies = [ [[package]] name = "modlist" -version = "0.10.0" +version = "0.11.0" dependencies = [ "chrono", "dirs", diff --git a/Cargo.toml b/Cargo.toml index 0b6ffa4..c86633a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "modlist" -version = "0.10.0" +version = "0.11.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/src/apis/modrinth.rs b/src/apis/modrinth.rs index f3f89a7..bb5ee19 100644 --- a/src/apis/modrinth.rs +++ b/src/apis/modrinth.rs @@ -108,7 +108,7 @@ pub struct Hash { pub sha1: String, } -async fn get(api: String, path: String) -> Result>, Box> { +async fn get(api: &str, path: String) -> Result>, Box> { let url = format!(r#"{}{}"#, api, path); let client = Client::builder() @@ -131,14 +131,14 @@ async fn get(api: String, path: String) -> Result>, Box Project { +pub async fn project(api: &str, name: &str) -> Project { let url = format!("project/{}", name); let data = get(api, url).await.unwrap().unwrap(); serde_json::from_slice(&data).unwrap() } -pub async fn projects(api: String, ids: Vec) -> Vec { +pub async fn projects(api: &str, ids: Vec) -> Vec { let all = ids.join(r#"",""#); let url = format!(r#"projects?ids=["{}"]"#, all); @@ -147,7 +147,8 @@ pub async fn projects(api: String, ids: Vec) -> Vec { serde_json::from_slice(&data).unwrap() } -pub async fn versions(api: String, id: String, list: List) -> Vec { +///Get applicable versions from mod_id with list context +pub async fn versions(api: &str, id: String, list: List) -> Vec { let loaderstr = match list.modloader { Modloader::Forge => String::from("forge"), Modloader::Fabric => String::from("fabric"), @@ -163,9 +164,8 @@ pub async fn versions(api: String, id: String, list: List) -> Vec { } } -pub async fn get_raw_versions(api: String, versions: Vec) -> Vec { - println!("Getting versions {}", &versions.join(", ")); - +///Get version with the version ids +pub async fn get_raw_versions(api: &str, versions: Vec) -> Vec { let url = format!(r#"versions?ids=["{}"]"#, versions.join(r#"",""#)); let data = get(api, url).await.unwrap().unwrap(); @@ -204,7 +204,7 @@ pub struct MCVersion { pub major: bool, } -pub async fn get_minecraft_version(api: String, version: MCVersionType) -> String { +pub async fn get_minecraft_version(api: &str, version: MCVersionType) -> String { let data = get(api, String::from("tag/game_version")).await.unwrap().unwrap(); let mc_versions: Vec = serde_json::from_slice(&data).unwrap(); let ver = match version { diff --git a/src/commands/download.rs b/src/commands/download.rs index 7748d15..2714630 100644 --- a/src/commands/download.rs +++ b/src/commands/download.rs @@ -47,7 +47,7 @@ pub async fn download(config: Cfg, input: Input) -> MLE<()> { if input.clean { clean_list_dir(¤t_list)? }; if !to_download.is_empty() { - download_versions(current_list.clone(), config.clone(), get_raw_versions(String::from(&config.apis.modrinth), to_download).await).await?; + download_versions(current_list.clone(), config.clone(), get_raw_versions(&config.apis.modrinth, to_download).await).await?; } else { println!("There are no new versions to download"); } diff --git a/src/commands/io.rs b/src/commands/io.rs index 44604d1..a3d056f 100644 --- a/src/commands/io.rs +++ b/src/commands/io.rs @@ -2,7 +2,7 @@ use std::fs::File; use std::io::prelude::*; use serde::{Serialize, Deserialize}; -use crate::{input::{Input, IoOptions}, db::{lists_get, userlist_get_all_ids, lists_get_all_ids, lists_insert}, config::Cfg, Modloader, List, devdir, error::MLE, mods_add}; +use crate::{input::{Input, IoOptions}, db::{lists_get, userlist_get_all_ids, lists_get_all_ids, lists_insert}, config::Cfg, Modloader, List, devdir, error::MLE, mods_add, IDSelector}; #[derive(Debug, Serialize, Deserialize)] struct Export { @@ -82,7 +82,7 @@ async fn import(config: Cfg, input: Input) -> MLE<()> { let mods: Vec<&str> = exportlist.mods.split('|').collect(); let mut mod_ids = vec![]; for mod_id in mods { - mod_ids.push(String::from(mod_id)); + mod_ids.push(IDSelector::ModificationID(String::from(mod_id))); }; //TODO impl set_version and good direct download //TODO impl all at once, dafuck diff --git a/src/commands/modification.rs b/src/commands/modification.rs index 12a635f..c815155 100644 --- a/src/commands/modification.rs +++ b/src/commands/modification.rs @@ -1,8 +1,10 @@ -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}}; +use crate::{modrinth::{versions, extract_current_version, Version, projects, get_raw_versions, project}, 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 { - +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum IDSelector { + ModificationID(String), + VersionID(String) } pub async fn modification(config: Cfg, input: Input) -> MLE<()> { @@ -22,27 +24,148 @@ async fn add(config: Cfg, input: Input) -> MLE<()> { Ok(()) } -//TODO impl specific version -pub async fn mods_add(config: Cfg, mod_id: Vec, list: List, direct_download: bool, set_version: bool) -> MLE<()> { - + +#[derive(Debug, Clone)] +pub struct ProjectInfo { + pub mod_id: String, + pub slug: String, + pub title: String, + pub current_version: Option, + pub applicable_versions: Vec, + pub download_link: String, +} + +//TODO impl specific version... Rewrite yay +pub async fn mods_add(config: Cfg, ids: 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 mod_ids: Vec = Vec::new(); + let mut ver_ids: Vec = Vec::new(); + + //"Sort" project ids from version ids to be able to handle them differently but in a batch + for id in ids { + match id { + IDSelector::ModificationID(pid) => mod_ids.push(pid), + IDSelector::VersionID(vid) => ver_ids.push(vid), + } + } - let mut downloadstack: Vec = Vec::new(); + let mut projectinfo: Vec = Vec::new(); + if !mod_ids.is_empty() { projectinfo.append(&mut get_mod_infos(config.clone(), mod_ids, list.clone()).await?) }; + if !ver_ids.is_empty() { projectinfo.append(&mut get_ver_info(config.clone(), ver_ids).await?) }; + + if projectinfo.is_empty() { return Err(MLError::new(ErrorType::ArgumentError, "NO_IDS?")) }; - for project in projects { + let mut downloadstack: Vec = Vec::new(); + + //Adding each mod to the lists and downloadstack + for project in projectinfo { + let current_version_id = if project.current_version.is_none() { String::from("NONE") } else { project.current_version.clone().unwrap().id }; + + match userlist_insert(config.clone(), &list.id, &project.mod_id, ¤t_version_id, project.clone().applicable_versions, &project.download_link, 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.mod_id, &project.slug, &project.title) { + Err(e) => { + if e.to_string() == "SQL: UNIQUE constraint failed: mods.id" { Ok(..) } else { Err(e) } + }, + Ok(..) => Ok(..), + }?; + + if project.current_version.is_some() { downloadstack.push(project.current_version.unwrap()) }; + } + + //Download all the added mods + if direct_download { + download_versions(list.clone(), config.clone(), downloadstack).await?; + }; + + + // let projects = if id.len() == 1 { + // vec![project(String::from(&config.apis.modrinth), &mod_id).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(()) +} + +async fn get_mod_infos(config: Cfg, mod_ids: Vec, list: List) -> MLE> { + let mut projectinfo: Vec = Vec::new(); + + //Get required information from mod_ids + let m_projects = match mod_ids.len() { + 1 => vec![project(&config.apis.modrinth, &mod_ids[0]).await], + 2.. => projects(&config.apis.modrinth, mod_ids).await, + _ => panic!("PANIC"), + }; + for project in m_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 available_versions = versions(&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())?; @@ -50,49 +173,55 @@ pub async fn mods_add(config: Cfg, mod_id: Vec, list: List, direct_downl 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); }; + + projectinfo.push(ProjectInfo { mod_id: project.id, slug: project.slug, title: project.title, current_version, applicable_versions: available_versions_vec, download_link: file }) + } 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")); + projectinfo.push(ProjectInfo { mod_id: project.id, slug: project.slug, title: project.title, current_version, applicable_versions: available_versions_vec, download_link: file }) } + }; - 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(..), - }?; + Ok(projectinfo) +} - downloadstack.push(current_version.unwrap()); +async fn get_ver_info(config: Cfg, ver_ids: Vec) -> MLE> { + let mut projectinfo: Vec = Vec::new(); + + //Get required information from ver_ids + let mut v_versions = get_raw_versions(&config.apis.modrinth, ver_ids).await; + let mut v_mod_ids: Vec = Vec::new(); + for ver in v_versions.clone() { + v_mod_ids.push(ver.project_id); }; - - //Download all the added mods - if direct_download { - download_versions(list.clone(), config.clone(), downloadstack).await?; + let mut v_projects = projects(&config.apis.modrinth, v_mod_ids).await; + v_versions.sort_by(|a, b| a.project_id.cmp(&b.project_id)); + v_projects.sort_by(|a, b| a.id.cmp(&b.id)); + + for (i, project) in v_projects.into_iter().enumerate() { + let version = &v_versions[i]; + println!("\t└{}({})", project.title, version.id); + let file = version.clone().files.into_iter().find(|f| f.primary).unwrap().url; + projectinfo.push(ProjectInfo { mod_id: project.id, slug: project.slug, title: project.title, current_version: Some(version.clone()), applicable_versions: vec![String::from(&version.id)], download_link: file }) }; - - Ok(()) + Ok(projectinfo) } fn remove(config: Cfg, input: Input) -> MLE<()> { - - let mod_id = mods_get_id(&config.data, input.mod_id.as_ref().unwrap())?; + + let id = match input.clone().mod_id.unwrap() { + IDSelector::ModificationID(id) => id, + IDSelector::VersionID(..) => return Err(MLError::new(ErrorType::ArgumentError, "NO_MOD_ID")), + }; + + let mod_id = mods_get_id(&config.data, &id)?; let version = userlist_get_current_version(config.clone(), input.clone().list.unwrap().id, String::from(&mod_id))?; diff --git a/src/commands/update.rs b/src/commands/update.rs index bc5b316..75bee39 100644 --- a/src/commands/update.rs +++ b/src/commands/update.rs @@ -1,4 +1,4 @@ -use crate::{config::Cfg, modrinth::{versions, extract_current_version, Version}, get_current_list, db::{userlist_get_all_ids, userlist_get_applicable_versions, userlist_change_versions, lists_get_all_ids, lists_get, userlist_get_current_version, mods_get_title, userlist_get_set_version}, List, input::Input, files::{delete_version, download_versions, disable_version, clean_list_dir}, error::{MLE, MLError, ErrorType}}; +use crate::{config::Cfg, modrinth::{versions, extract_current_version, Version}, get_current_list, db::{userlist_get_all_ids, userlist_get_applicable_versions, userlist_change_versions, lists_get_all_ids, lists_get, userlist_get_current_version, userlist_get_set_version, mods_get_info}, List, input::Input, files::{delete_version, download_versions, disable_version, clean_list_dir}, error::{MLE, MLError, ErrorType}}; pub async fn update(config: Cfg, input: Input) -> MLE<()> { let mut liststack: Vec = vec![]; @@ -25,8 +25,8 @@ pub async fn cmd_update(config: Cfg, liststack: Vec, clean: bool, direct_d let mut updatestack: Vec = vec![]; for id in mods { - let title = mods_get_title(config.clone(), &id)?; - println!("\t└{}", title); + let info = mods_get_info(config.clone(), &id)?; + println!("\t└{}", info.title); if userlist_get_set_version(config.clone(), ¤t_list.id, &id)? { println!("\t └Set version, skipping update"); @@ -78,7 +78,7 @@ pub async fn cmd_update(config: Cfg, liststack: Vec, clean: bool, direct_d } async fn specific_update(config: Cfg, clean: bool, list: List, id: String) -> MLE { - let applicable_versions = versions(String::from(&config.apis.modrinth), String::from(&id), list.clone()).await; + let applicable_versions = versions(&config.apis.modrinth, String::from(&id), list.clone()).await; let mut versions: Vec = vec![]; diff --git a/src/db.rs b/src/db.rs index ecc6854..a7c149c 100644 --- a/src/db.rs +++ b/src/db.rs @@ -82,23 +82,29 @@ pub fn mods_get_id(data: &str, slug: &str) -> MLE { Ok(mod_id) } -pub fn mods_get_title(config: Cfg, id: &str) -> MLE { +pub struct ModInfo { + pub slug: String, + pub title: String, +} + +pub fn mods_get_info(config: Cfg, id: &str) -> MLE { let data = devdir(format!("{}/data.db", config.data).as_str()); let connection = Connection::open(data)?; - let mut mod_name = String::new(); - let mut stmt = connection.prepare("SELECT title FROM mods WHERE id = ?")?; + let mut mod_info: Option = None; + let mut stmt = connection.prepare("SELECT title, slug FROM mods WHERE id = ?")?; let name_iter = stmt.query_map([id], |row| { - row.get::(0) + Ok(vec![row.get::(0)?, row.get::(1)?]) })?; - for name in name_iter { - mod_name = name?; + for info in name_iter { + let i = info?; + mod_info = Some(ModInfo { title: String::from(&i[0]), slug: String::from(&i[1]) }); }; - match mod_name.is_empty() { + match mod_info.is_none() { true => Err(MLError::new(ErrorType::DBError, "GN_MOD_NOT_FOUND")), - false => Ok(mod_name), + false => Ok(mod_info.unwrap()), } } diff --git a/src/files.rs b/src/files.rs index b9325ea..6519c6a 100644 --- a/src/files.rs +++ b/src/files.rs @@ -2,7 +2,7 @@ use std::{fs::{File, read_dir, remove_file, rename}, io::Write, collections::Has use futures_util::StreamExt; use reqwest::Client; -use crate::{List, modrinth::Version, db::{userlist_add_disabled_versions, mods_get_title}, config::Cfg, error::{MLE, MLError, ErrorType}}; +use crate::{List, modrinth::Version, db::{userlist_add_disabled_versions, mods_get_info}, config::Cfg, error::{MLE, MLError, ErrorType}}; pub async fn download_versions(list: List, config: Cfg, versions: Vec) -> MLE { @@ -11,8 +11,8 @@ pub async fn download_versions(list: List, config: Cfg, versions: Vec) println!(" └Download mods to {}", dl_path); for ver in versions { - let project_name = mods_get_title(config.clone(), &ver.project_id)?; - print!("\t└({})Download version {}", project_name, ver.id); + let project_info = mods_get_info(config.clone(), &ver.project_id)?; + print!("\t└({})Download version {}", project_info.title, ver.id); //Force flush of stdout, else print! doesn't print instantly std::io::stdout().flush().unwrap(); let primary_file = ver.files.into_iter().find(|file| file.primary).unwrap(); diff --git a/src/input.rs b/src/input.rs index 17fc773..6c62ab7 100644 --- a/src/input.rs +++ b/src/input.rs @@ -1,11 +1,10 @@ -use crate::{error::{MLE, MLError, ErrorType}, Modloader, config::Cfg, db::lists_get, get_current_list, List, modrinth::{get_minecraft_version, MCVersionType}}; +use crate::{error::{MLE, MLError, ErrorType}, Modloader, config::Cfg, db::lists_get, get_current_list, List, modrinth::{get_minecraft_version, MCVersionType}, IDSelector}; #[derive(Debug, Clone, PartialEq, Eq)] pub struct Input { pub command: Option, pub mod_options: Option, - pub mod_id: Option, - pub mod_version: Option, + pub mod_id: Option, pub set_version: bool, pub all_lists: bool, pub clean: bool, @@ -61,8 +60,7 @@ impl Input { 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 mod_id: Option = None; let mut set_version = false; let mut all_lists = false; let mut clean = false; @@ -93,15 +91,17 @@ impl Input { command = Some(Cmd::Mod); mod_options = Some(ModOptions::Add); if arg_split.len() == 2 { - mod_id = Some(String::from(arg_split[1])); + mod_id = Some(IDSelector::ModificationID(String::from(arg_split[1]))); } else { return Err(MLError::new(ErrorType::ArgumentError, "Please specify a list mod slug or id")); } }, //TODO impl this "mv" => { + command = Some(Cmd::Mod); + mod_options = Some(ModOptions::Add); if arg_split.len() == 2 { - mod_version = Some(String::from(arg_split[1])); + mod_id = Some(IDSelector::VersionID(String::from(arg_split[1]))); } else { return Err(MLError::new(ErrorType::ArgumentError, "Please specify a version id")); }; @@ -110,7 +110,7 @@ impl Input { command = Some(Cmd::Mod); mod_options = Some(ModOptions::Remove); if arg_split.len() == 2 { - mod_id = Some(String::from(arg_split[1])); + mod_id = Some(IDSelector::ModificationID(String::from(arg_split[1]))); } else { return Err(MLError::new(ErrorType::ArgumentError, "Please specify a mod id")); }; @@ -206,7 +206,6 @@ impl Input { command, mod_options, mod_id, - mod_version, set_version, all_lists, clean, @@ -242,7 +241,7 @@ fn check_mod(mut input: Input, config: Cfg) -> MLE { }; match input.clone().mod_options.unwrap() { ModOptions::Add => { - if input.mod_id.is_none() && input.mod_version.is_none() { return Err(MLError::new(ErrorType::ArgumentError, "No mod id/slug or version id")); }; + if input.mod_id.is_none() { return Err(MLError::new(ErrorType::ArgumentError, "No mod id/slug or version id")); }; if input.list_id.is_none() { input.list = Some(get_current_list(config)?); }; Ok(input) }, @@ -263,7 +262,7 @@ async fn check_list(mut input: Input, config: Cfg) -> MLE { if input.list_id.is_none() { return Err(MLError::new(ErrorType::ArgumentError, "no list id specified")); }; if input.list_mcversion.is_none() { println!("No Minecraft Version specified, defaulting to latest release"); - input.list_mcversion = Some(get_minecraft_version(config.apis.modrinth, MCVersionType::Release).await); + input.list_mcversion = Some(get_minecraft_version(&config.apis.modrinth, MCVersionType::Release).await); }; if input.directory.is_none() { let id = input.clone().list_id.unwrap(); @@ -300,7 +299,6 @@ fn input_from() { command: Some(Cmd::List), mod_options: None, mod_id: None, - mod_version: None, set_version: false, all_lists: false, clean: false, @@ -327,8 +325,7 @@ async fn get_input_test() { Input { command: Some(Cmd::Mod), mod_options: Some(ModOptions::Add), - mod_id: Some(String::from("test")), - mod_version: None, + mod_id: Some(IDSelector::ModificationID(String::from("test"))), set_version: false, all_lists: false, clean: false, -- cgit v1.2.3