summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/commands/download.rs12
-rw-r--r--src/commands/io.rs29
-rw-r--r--src/commands/list.rs53
-rw-r--r--src/commands/modification.rs44
-rw-r--r--src/commands/update.rs22
-rw-r--r--src/config.rs2
-rw-r--r--src/db.rs10
-rw-r--r--src/lib.rs20
-rw-r--r--src/main.rs278
9 files changed, 289 insertions, 181 deletions
diff --git a/src/commands/download.rs b/src/commands/download.rs
index 2714630..4baecee 100644
--- a/src/commands/download.rs
+++ b/src/commands/download.rs
@@ -1,10 +1,10 @@
1use crate::{files::{get_downloaded_versions, download_versions, delete_version, disable_version, clean_list_dir}, db::{userlist_get_all_current_versions_with_mods, lists_get_all_ids, lists_get}, modrinth::get_raw_versions, error::{MLE, ErrorType, MLError}}; 1use crate::{files::{get_downloaded_versions, download_versions, delete_version, disable_version, clean_list_dir}, db::{userlist_get_all_current_versions_with_mods, lists_get_all_ids, lists_get}, modrinth::get_raw_versions, error::{MLE, ErrorType, MLError}};
2use crate::{List, get_current_list, config::Cfg, input::Input}; 2use crate::{List, get_current_list, config::Cfg};
3 3
4pub async fn download(config: Cfg, input: Input) -> MLE<()> { 4pub async fn download(config: Cfg, all_lists: bool, clean: bool, delete_old: bool) -> MLE<()> {
5 5
6 let mut liststack: Vec<List> = vec![]; 6 let mut liststack: Vec<List> = vec![];
7 if input.all_lists { 7 if all_lists {
8 let list_ids = lists_get_all_ids(config.clone())?; 8 let list_ids = lists_get_all_ids(config.clone())?;
9 for id in list_ids { 9 for id in list_ids {
10 liststack.push(lists_get(config.clone(), id)?); 10 liststack.push(lists_get(config.clone(), id)?);
@@ -33,7 +33,7 @@ pub async fn download(config: Cfg, input: Input) -> MLE<()> {
33 33
34 let current_download = downloaded_versions.get(&mod_id); 34 let current_download = downloaded_versions.get(&mod_id);
35 35
36 if current_download.is_none() || input.clean { 36 if current_download.is_none() || clean {
37 to_download.push(current_version); 37 to_download.push(current_version);
38 } else { 38 } else {
39 let downloaded_version = current_download.ok_or("SOMETHING_HAS_REALLY_GONE_WRONG").unwrap(); 39 let downloaded_version = current_download.ok_or("SOMETHING_HAS_REALLY_GONE_WRONG").unwrap();
@@ -44,7 +44,7 @@ pub async fn download(config: Cfg, input: Input) -> MLE<()> {
44 } 44 }
45 } 45 }
46 46
47 if input.clean { clean_list_dir(&current_list)? }; 47 if clean { clean_list_dir(&current_list)? };
48 48
49 if !to_download.is_empty() { 49 if !to_download.is_empty() {
50 download_versions(current_list.clone(), config.clone(), get_raw_versions(&config.apis.modrinth, to_download).await).await?; 50 download_versions(current_list.clone(), config.clone(), get_raw_versions(&config.apis.modrinth, to_download).await).await?;
@@ -54,7 +54,7 @@ pub async fn download(config: Cfg, input: Input) -> MLE<()> {
54 54
55 if !to_disable.is_empty() { 55 if !to_disable.is_empty() {
56 for ver in to_disable { 56 for ver in to_disable {
57 if input.delete_old { 57 if delete_old {
58 println!("Deleting version {} for mod {}", ver.1, ver.0); 58 println!("Deleting version {} for mod {}", ver.1, ver.0);
59 delete_version(current_list.clone(), ver.1)?; 59 delete_version(current_list.clone(), ver.1)?;
60 } else { 60 } else {
diff --git a/src/commands/io.rs b/src/commands/io.rs
index a3d056f..5de8dd1 100644
--- a/src/commands/io.rs
+++ b/src/commands/io.rs
@@ -2,7 +2,7 @@ use std::fs::File;
2use std::io::prelude::*; 2use std::io::prelude::*;
3use serde::{Serialize, Deserialize}; 3use serde::{Serialize, Deserialize};
4 4
5use 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}; 5use crate::{db::{lists_get, userlist_get_all_ids, lists_get_all_ids, lists_insert}, config::Cfg, Modloader, List, devdir, error::MLE, mod_add, IDSelector};
6 6
7#[derive(Debug, Serialize, Deserialize)] 7#[derive(Debug, Serialize, Deserialize)]
8struct Export { 8struct Export {
@@ -32,22 +32,12 @@ impl ExportList {
32 } 32 }
33} 33}
34 34
35pub async fn io(config: Cfg, input: Input) -> MLE<()> { 35pub fn export(config: Cfg, list: Option<String>) -> MLE<()> {
36
37 match input.clone().io_options.unwrap() {
38 IoOptions::Export => { export(config, input)? },
39 IoOptions::Import => { import(config, input).await? },
40 }
41
42 Ok(())
43}
44
45fn export(config: Cfg, input: Input) -> MLE<()> {
46 let mut list_ids: Vec<String> = vec![]; 36 let mut list_ids: Vec<String> = vec![];
47 if input.all_lists { 37 if list.is_none() {
48 list_ids = lists_get_all_ids(config.clone())?; 38 list_ids = lists_get_all_ids(config.clone())?;
49 } else { 39 } else {
50 list_ids.push(lists_get(config.clone(), input.list.unwrap().id)?.id); 40 list_ids.push(lists_get(config.clone(), list.unwrap())?.id);
51 } 41 }
52 let mut lists: Vec<ExportList> = vec![]; 42 let mut lists: Vec<ExportList> = vec![];
53 for list_id in list_ids { 43 for list_id in list_ids {
@@ -64,14 +54,9 @@ fn export(config: Cfg, input: Input) -> MLE<()> {
64 Ok(()) 54 Ok(())
65} 55}
66 56
67async fn import(config: Cfg, input: Input) -> MLE<()> { 57pub async fn import(config: Cfg, file_str: String, direct_download: bool) -> MLE<()> {
68 58
69 let filestr: String = match input.file { 59 let mut file = File::open(file_str)?;
70 Some(args) => args,
71 None => devdir(dirs::home_dir().unwrap().join("mlexport.toml").into_os_string().into_string().unwrap().as_str()),
72 };
73
74 let mut file = File::open(filestr)?;
75 let mut content = String::new(); 60 let mut content = String::new();
76 file.read_to_string(&mut content)?; 61 file.read_to_string(&mut content)?;
77 let export: Export = toml::from_str(&content)?; 62 let export: Export = toml::from_str(&content)?;
@@ -86,7 +71,7 @@ async fn import(config: Cfg, input: Input) -> MLE<()> {
86 }; 71 };
87 //TODO impl set_version and good direct download 72 //TODO impl set_version and good direct download
88 //TODO impl all at once, dafuck 73 //TODO impl all at once, dafuck
89 mods_add(config.clone(), mod_ids, list, input.direct_download, false).await?; 74 mod_add(config.clone(), mod_ids, list, direct_download, false).await?;
90 } 75 }
91 Ok(()) 76 Ok(())
92} 77}
diff --git a/src/commands/list.rs b/src/commands/list.rs
index 8e86973..80e801a 100644
--- a/src/commands/list.rs
+++ b/src/commands/list.rs
@@ -1,4 +1,4 @@
1use crate::{db::{lists_insert, lists_remove, config_change_current_list, config_get_current_list, lists_get, lists_version}, Modloader, config::Cfg, input::{Input, ListOptions}, cmd_update, error::MLE}; 1use crate::{db::{lists_insert, lists_remove, config_change_current_list, config_get_current_list, lists_get, lists_version}, Modloader, config::Cfg, update, error::MLE};
2 2
3#[derive(Debug, Clone, PartialEq, Eq)] 3#[derive(Debug, Clone, PartialEq, Eq)]
4pub struct List { 4pub struct List {
@@ -8,44 +8,23 @@ pub struct List {
8 pub download_folder: String, 8 pub download_folder: String,
9} 9}
10 10
11pub async fn list(config: Cfg, input: Input) -> MLE<()> {
12
13 match input.clone().list_options.unwrap() {
14 ListOptions::Add => {
15 add(config, input)
16 },
17 ListOptions::Change => {
18 change(config, input)
19 },
20 ListOptions::Remove => {
21 remove(config, input)
22 },
23 ListOptions::Version => {
24 version(config, input).await
25 }
26 }
27}
28
29pub fn get_current_list(config: Cfg) -> MLE<List> { 11pub fn get_current_list(config: Cfg) -> MLE<List> {
30 let id = config_get_current_list(config.clone())?; 12 let id = config_get_current_list(config.clone())?;
31 lists_get(config, id) 13 lists_get(config, id)
32} 14}
33 15
34fn add(config: Cfg, input: Input) -> MLE<()> { 16pub fn list_add(config: Cfg, id: String, mc_version: String, modloader: Modloader, directory: String) -> MLE<()> {
35 let id = input.list_id.unwrap(); 17 lists_insert(config, id, mc_version, modloader, directory)
36 let mc_version = input.list_mcversion.unwrap();
37 let mod_loader = input.modloader.unwrap();
38 let download_folder = input.directory.unwrap();
39 lists_insert(config, id, mc_version, mod_loader, download_folder)
40} 18}
41 19
42fn change(config: Cfg, input: Input) -> MLE<()> { 20pub fn list_change(config: Cfg, id: String) -> MLE<()> {
43 println!("Change default list to: {}", input.clone().list.unwrap().id); 21 //TODO check if list exists
44 config_change_current_list(config, input.list.unwrap().id) 22 println!("Change default list to: {}", id);
23 config_change_current_list(config, id)
45} 24}
46 25
47fn remove(config: Cfg, input: Input) -> MLE<()> { 26pub fn list_remove(config: Cfg, id: String) -> MLE<()> {
48 lists_remove(config, input.list.unwrap().id) 27 lists_remove(config, id)
49} 28}
50 29
51///Changing the current lists version and updating it 30///Changing the current lists version and updating it
@@ -54,14 +33,12 @@ fn remove(config: Cfg, input: Input) -> MLE<()> {
54/// 33///
55/// * `config` - The current config 34/// * `config` - The current config
56/// * `args` - All args, to extract the new version 35/// * `args` - All args, to extract the new version
57async fn version(config: Cfg, input: Input) -> MLE<()> { 36pub async fn list_version(config: Cfg, id: String, mc_version: String, download: bool, delete: bool) -> MLE<()> {
58 println!("Change version for list {} to minecraft version: {}", input.clone().list.unwrap().id, input.clone().list_mcversion.unwrap()); 37 println!("Change version for list {} to minecraft version: {}", id, mc_version);
59 38
60 lists_version(config.clone(), input.clone().list.ok_or("").unwrap().id, input.clone().list_mcversion.ok_or("").unwrap())?; 39 lists_version(config.clone(), &id, &mc_version)?;
61
62 //Linebreak readability
63 println!("");
64 40
65 println!("Check for updates for new minecraft version in list {}", input.clone().list.unwrap().id); 41 println!("\nCheck for updates for new minecraft version in list {}", id);
66 cmd_update(config, vec![input.list.ok_or("").unwrap()], true, input.direct_download, input.delete_old).await 42 let list = lists_get(config.clone(), id)?;
43 update(config, vec![list], true, download, delete).await
67} 44}
diff --git a/src/commands/modification.rs b/src/commands/modification.rs
index 31e50af..454e148 100644
--- a/src/commands/modification.rs
+++ b/src/commands/modification.rs
@@ -1,4 +1,4 @@
1use 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}}; 1use 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}, files::{delete_version, download_versions}, List, error::{MLE, ErrorType, MLError}};
2 2
3#[derive(Debug, Clone, PartialEq, Eq)] 3#[derive(Debug, Clone, PartialEq, Eq)]
4pub enum IDSelector { 4pub enum IDSelector {
@@ -6,24 +6,6 @@ pub enum IDSelector {
6 VersionID(String) 6 VersionID(String)
7} 7}
8 8
9pub async fn modification(config: Cfg, input: Input) -> MLE<()> {
10 match input.clone().mod_options.ok_or("").unwrap() {
11 ModOptions::Add => {
12 add(config, input).await
13 },
14 ModOptions::Remove => {
15 remove(config, input)
16 },
17 }
18}
19
20async fn add(config: Cfg, input: Input) -> MLE<()> {
21
22 mods_add(config, vec![input.mod_id.unwrap()], input.list.unwrap(), input.direct_download, input.set_version).await?;
23
24 Ok(())
25}
26
27#[derive(Debug, Clone)] 9#[derive(Debug, Clone)]
28pub struct ProjectInfo { 10pub struct ProjectInfo {
29 pub mod_id: String, 11 pub mod_id: String,
@@ -34,7 +16,7 @@ pub struct ProjectInfo {
34 pub download_link: String, 16 pub download_link: String,
35} 17}
36 18
37pub async fn mods_add(config: Cfg, ids: Vec<IDSelector>, list: List, direct_download: bool, set_version: bool) -> MLE<()> { 19pub async fn mod_add(config: Cfg, ids: Vec<IDSelector>, list: List, direct_download: bool, set_version: bool) -> MLE<()> {
38 println!("Add mods to {}", list.id); 20 println!("Add mods to {}", list.id);
39 println!(" â””Add mods:"); 21 println!(" â””Add mods:");
40 22
@@ -156,22 +138,24 @@ async fn get_ver_info(config: Cfg, ver_ids: Vec<String>) -> MLE<Vec<ProjectInfo>
156 Ok(projectinfo) 138 Ok(projectinfo)
157} 139}
158 140
159fn remove(config: Cfg, input: Input) -> MLE<()> { 141/// Remove mod from a list
160 142/// # Arguments
161 let id = match input.clone().mod_id.unwrap() { 143///
162 IDSelector::ModificationID(id) => id, 144/// * `config` - config struct
163 IDSelector::VersionID(..) => return Err(MLError::new(ErrorType::ArgumentError, "NO_MOD_ID")), 145/// * `id` - name, slug or id of the mod
164 }; 146/// * `list` - List struct
147pub fn mod_remove(config: Cfg, id: &str, list: List) -> MLE<()> {
165 148
166 let mod_id = mods_get_id(&config.data, &id)?; 149 let mod_id = mods_get_id(&config.data, id)?;
167 150
168 let version = userlist_get_current_version(config.clone(), input.clone().list.unwrap().id, String::from(&mod_id))?; 151 let version = userlist_get_current_version(config.clone(), &list.id, &mod_id)?;
169 152
170 userlist_remove(config.clone(), input.clone().list.unwrap().id, String::from(&mod_id))?; 153 userlist_remove(config.clone(), &list.id, &mod_id)?;
171 delete_version(input.list.unwrap(), version)?; 154 delete_version(list, version)?;
172 155
173 let list_ids = lists_get_all_ids(config.clone())?; 156 let list_ids = lists_get_all_ids(config.clone())?;
174 157
158 // Remove mod from main list if not used elsewhere
175 let mut mod_used = false; 159 let mut mod_used = false;
176 for id in list_ids { 160 for id in list_ids {
177 let mods = userlist_get_all_ids(config.clone(), id)?; 161 let mods = userlist_get_all_ids(config.clone(), id)?;
diff --git a/src/commands/update.rs b/src/commands/update.rs
index 75bee39..e5751c0 100644
--- a/src/commands/update.rs
+++ b/src/commands/update.rs
@@ -1,21 +1,6 @@
1use 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}}; 1use crate::{config::Cfg, modrinth::{versions, extract_current_version, Version}, db::{userlist_get_all_ids, userlist_get_applicable_versions, userlist_change_versions, userlist_get_current_version, userlist_get_set_version, mods_get_info}, List, files::{delete_version, download_versions, disable_version, clean_list_dir}, error::{MLE, MLError, ErrorType}};
2
3pub async fn update(config: Cfg, input: Input) -> MLE<()> {
4 let mut liststack: Vec<List> = vec![];
5 if input.all_lists {
6 let list_ids = lists_get_all_ids(config.clone())?;
7 for id in list_ids {
8 liststack.push(lists_get(config.clone(), id)?);
9 }
10 } else {
11 let current = get_current_list(config.clone())?;
12 println!("Update list {}:", current.id);
13 liststack.push(current)
14 }
15 cmd_update(config, liststack, input.clean, input.direct_download, input.delete_old).await
16}
17 2
18pub async fn cmd_update(config: Cfg, liststack: Vec<List>, clean: bool, direct_download: bool, delete_old: bool) -> MLE<()> { 3pub async fn update(config: Cfg, liststack: Vec<List>, clean: bool, direct_download: bool, delete_old: bool) -> MLE<()> {
19 for current_list in liststack { 4 for current_list in liststack {
20 let mods = userlist_get_all_ids(config.clone(), current_list.clone().id)?; 5 let mods = userlist_get_all_ids(config.clone(), current_list.clone().id)?;
21 6
@@ -34,7 +19,7 @@ pub async fn cmd_update(config: Cfg, liststack: Vec<List>, clean: bool, direct_d
34 } 19 }
35 20
36 //Getting current installed version for disable or delete 21 //Getting current installed version for disable or delete
37 let disable_version = userlist_get_current_version(config.clone(), String::from(&current_list.id), String::from(&id))?; 22 let disable_version = userlist_get_current_version(config.clone(), &current_list.id, &id)?;
38 23
39 updatestack.push( 24 updatestack.push(
40 match specific_update(config.clone(), clean, current_list.clone(), String::from(&id)).await { 25 match specific_update(config.clone(), clean, current_list.clone(), String::from(&id)).await {
@@ -110,6 +95,7 @@ async fn specific_update(config: Cfg, clean: bool, list: List, id: String) -> ML
110 }?; 95 }?;
111 current.push(current_ver.clone()); 96 current.push(current_ver.clone());
112 97
98 //TODO implement version selection if no primary
113 let link = match current_ver.files.into_iter().find(|f| f.primary).ok_or("!no primary in links") { 99 let link = match current_ver.files.into_iter().find(|f| f.primary).ok_or("!no primary in links") {
114 Ok(p) => Ok(p), 100 Ok(p) => Ok(p),
115 Err(e) => Err(MLError::new(ErrorType::Other, e)), 101 Err(e) => Err(MLError::new(ErrorType::Other, e)),
diff --git a/src/config.rs b/src/config.rs
index ded0062..075d884 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -27,7 +27,7 @@ impl Cfg {
27 let default_cfg = Cfg { data: String::from("./"), apis: Apis { modrinth: String::from("https://api.modrinth.com/v2/") } }; 27 let default_cfg = Cfg { data: String::from("./"), apis: Apis { modrinth: String::from("https://api.modrinth.com/v2/") } };
28 let mut file = File::create(devdir(configfile.to_str().unwrap()))?; 28 let mut file = File::create(devdir(configfile.to_str().unwrap()))?;
29 println!("Created config file"); 29 println!("Created config file");
30 file.write_all(&toml::to_string(&default_cfg)?.as_bytes())?; 30 file.write_all(toml::to_string(&default_cfg)?.as_bytes())?;
31 File::open(devdir(configfile.to_str().unwrap()))? 31 File::open(devdir(configfile.to_str().unwrap()))?
32 } else { 32 } else {
33 return Err(err.into()); 33 return Err(err.into());
diff --git a/src/db.rs b/src/db.rs
index 9428466..2c48cab 100644
--- a/src/db.rs
+++ b/src/db.rs
@@ -49,6 +49,9 @@ pub fn mods_get_all_ids(config: Cfg) -> Result<Vec<String>, Box<dyn std::error::
49/// 49///
50///Will return `MLError` when no mod id is found 50///Will return `MLError` when no mod id is found
51pub fn mods_get_id(data: &str, slug: &str) -> MLE<String> { 51pub fn mods_get_id(data: &str, slug: &str) -> MLE<String> {
52
53 //TODO check if "slug" is id
54
52 let data = devdir(format!("{}/data.db", data).as_str()); 55 let data = devdir(format!("{}/data.db", data).as_str());
53 let connection = Connection::open(data)?; 56 let connection = Connection::open(data)?;
54 57
@@ -192,8 +195,7 @@ pub fn userlist_get_all_ids(config: Cfg, list_id: String) -> MLE<Vec<String>> {
192 } 195 }
193} 196}
194 197
195 198pub fn userlist_remove(config: Cfg, list_id: &str, mod_id: &str) -> MLE<()> {
196pub fn userlist_remove(config: Cfg, list_id: String, mod_id: String) -> MLE<()> {
197 let data = devdir(format!("{}/data.db", config.data).as_str()); 199 let data = devdir(format!("{}/data.db", config.data).as_str());
198 let connection = Connection::open(data)?; 200 let connection = Connection::open(data)?;
199 201
@@ -242,7 +244,7 @@ pub fn userlist_get_all_applicable_versions_with_mods(config: Cfg, list_id: Stri
242 Ok(versions) 244 Ok(versions)
243} 245}
244 246
245pub fn userlist_get_current_version(config: Cfg, list_id: String, mod_id: String) -> MLE<String> { 247pub fn userlist_get_current_version(config: Cfg, list_id: &str, mod_id: &str) -> MLE<String> {
246 let data = devdir(format!("{}/data.db", config.data).as_str()); 248 let data = devdir(format!("{}/data.db", config.data).as_str());
247 let connection = Connection::open(data).unwrap(); 249 let connection = Connection::open(data).unwrap();
248 250
@@ -425,7 +427,7 @@ pub fn lists_get(config: Cfg, list_id: String) -> MLE<List> {
425 Ok(list) 427 Ok(list)
426} 428}
427 429
428pub fn lists_version(config: Cfg, list_id: String, version: String) -> MLE<()> { 430pub fn lists_version(config: Cfg, list_id: &str, version: &str) -> MLE<()> {
429 let data = devdir(format!("{}/data.db", config.data).as_str()); 431 let data = devdir(format!("{}/data.db", config.data).as_str());
430 let connection = Connection::open(data).unwrap(); 432 let connection = Connection::open(data).unwrap();
431 433
diff --git a/src/lib.rs b/src/lib.rs
index eb845d8..8d97d1a 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -6,7 +6,7 @@ pub mod db;
6pub mod error; 6pub mod error;
7pub mod files; 7pub mod files;
8 8
9use std::path::Path; 9use std::{path::Path, fmt::Display};
10 10
11pub use apis::*; 11pub use apis::*;
12pub use commands::*; 12pub use commands::*;
@@ -19,14 +19,7 @@ pub enum Modloader {
19} 19}
20 20
21impl Modloader { 21impl Modloader {
22 fn to_string(&self) -> String { 22 pub fn from(string: &str) -> MLE<Modloader> {
23 match self {
24 Modloader::Fabric => String::from("fabric"),
25 Modloader::Forge => String::from("forge"),
26 }
27 }
28
29 fn from(string: &str) -> MLE<Modloader> {
30 match string { 23 match string {
31 "forge" => Ok(Modloader::Forge), 24 "forge" => Ok(Modloader::Forge),
32 "fabric" => Ok(Modloader::Fabric), 25 "fabric" => Ok(Modloader::Fabric),
@@ -35,6 +28,15 @@ impl Modloader {
35 } 28 }
36} 29}
37 30
31impl Display for Modloader {
32 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33 match self {
34 Modloader::Fabric => write!(f, "fabric"),
35 Modloader::Forge => write!(f, "forge"),
36 }
37 }
38}
39
38pub fn devdir(path: &str) -> String { 40pub fn devdir(path: &str) -> String {
39 let p = Path::new(path); 41 let p = Path::new(path);
40 let dev = std::env::var("DEV"); 42 let dev = std::env::var("DEV");
diff --git a/src/main.rs b/src/main.rs
index 32727c7..0dfc190 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,65 +1,237 @@
1use std::{env, process}; 1use clap::{Parser, Subcommand};
2use modlist::{config::Cfg, mod_add, mod_remove, db::{lists_get, config_get_current_list, lists_get_all_ids}, IDSelector, download, update, List, get_current_list, import, devdir, export, list_add, Modloader, list_version, list_remove, list_change};
2 3
3use modlist::{config::Cfg, input::{get_input, Cmd}, update, download, list, io, modification, setup}; 4//TODO make default list optional
5
6#[derive(Parser)]
7#[command(author, version, about)]
8struct Cli {
9 #[command(subcommand)]
10 command: Commands,
11}
12
13#[derive(Subcommand)]
14enum Commands {
15 r#Mod {
16 #[command(subcommand)]
17 command: ModCommands,
18 },
19 List {
20 #[command(subcommand)]
21 command: ListCommands
22 },
23 Download {
24 /// download all lists
25 #[arg(short, long)]
26 all: bool,
27
28 /// clean all mods before downloading them
29 #[arg(short, long)]
30 clean: bool,
31
32 /// remove disabled versions
33 #[arg(short, long)]
34 remove: bool,
35 },
36 Update {
37 /// download all lists
38 #[arg(short, long)]
39 all: bool,
40
41 /// directly download updated mods
42 #[arg(short, long)]
43 download: bool,
44
45 /// clean all mods before downloading them
46 #[arg(short, long)]
47 clean: bool,
48
49 /// delete disabled versions
50 #[arg(short, long)]
51 remove: bool,
52 },
53 Import {
54 #[arg(short, long)]
55 file: Option<String>,
56
57 /// directly download imported mods
58 #[arg(short, long)]
59 download: bool,
60 },
61 Export {
62 /// the list you want to export
63 list: Option<String>
64 }
65}
66
67#[derive(Subcommand)]
68enum ModCommands {
69 Add {
70 /// id of the mod/version
71 id: String,
72
73 /// set id mode to version
74 #[arg(short, long)]
75 version: bool,
76
77 /// directly download the mod
78 #[arg(short, long)]
79 download: bool,
80
81 /// lock the version added
82 #[arg(/* short , */long)]
83 lock: bool,
84
85 /// optional List selection, else default list will be used
86 #[arg(short, long)]
87 list: Option<String>
88 },
89 Remove {
90 /// id, name or title of the mod
91 id: String,
92
93 /// optional List selection, else default list will be used
94 #[arg(short, long)]
95 list: Option<String>
96 }
97}
98
99#[derive(Subcommand)]
100enum ListCommands {
101 Add {
102 /// list id
103 id: String,
104
105 directory: String,
106
107 modloader: Option<String>,
108
109 version: Option<String>,
110 },
111 Remove {
112 /// id, name or title of the list
113 id: String
114 },
115 List,
116 Change {
117 /// id of the list to change to
118 id: String
119 },
120 Version {
121 /// list id
122 id: String,
123 /// desired minecraft version
124 version: String,
125
126 /// directly download updated mods
127 #[arg(long, short)]
128 download: bool,
129
130 /// delete disabled versions
131 #[arg(short, long)]
132 remove: bool,
133 }
134}
4 135
5#[tokio::main] 136#[tokio::main]
6async fn main() { 137async fn main() {
138
139 let cli = Cli::parse();
140
7 let config = Cfg::init("modlist.toml").unwrap(); 141 let config = Cfg::init("modlist.toml").unwrap();
8 142 println!("{:?}", config);
9 let mut args: Vec<String> = env::args().collect(); 143
10 args.reverse(); 144 //TODO setup? maybe setup on install
11 args.pop(); 145 match cli.command {
12 args.reverse(); 146 Commands::Mod { command } => {
13 147
14 if args.is_empty() { 148 match command {
15 println!("Please enter an argument"); 149 #[allow(unused_variables)]
16 process::exit(1); 150 ModCommands::Add { id, version, list, download, lock } => {
17 }; 151 let listf = match list {
18 152 Some(list) => lists_get(config.clone(), list).unwrap(),
19 let input = match get_input(config.clone(), args).await { 153 None => lists_get(config.clone(), config_get_current_list(config.clone()).unwrap()).unwrap(),
20 Ok(i) => i, 154 };
21 Err(e) => { 155
22 println!("{}", e); 156 let marked_id = match version {
23 process::exit(1); 157 true => IDSelector::VersionID(id),
24 } 158 false => IDSelector::ModificationID(id),
25 }; 159 };
26 160
27 match input.clone().command.unwrap() { 161 mod_add(config, vec![marked_id], listf, download, lock).await
28 Cmd::Mod => { 162 }
29 modification(config, input).await 163 ModCommands::Remove { id, list } => {
30 }, 164 //TODO add output
31 Cmd::List => { 165 //TODO add success even if no file found
32 list(config, input).await 166 let listf = match list {
33 }, 167 Some(list) => lists_get(config.clone(), list).unwrap(),
34 Cmd::Update => { 168 None => lists_get(config.clone(), config_get_current_list(config.clone()).unwrap()).unwrap(),
35 update(config, input).await 169 };
36 }, 170 mod_remove(config, &id, listf)
37 Cmd::Download => { 171 }
38 download(config, input).await 172 }
39 }, 173 },
40 Cmd::Io => { 174 Commands::List { command } => {
41 io(config, input).await 175 match command {
176 ListCommands::Add { id, directory, modloader, version } => {
177 let ml = match modloader {
178 Some(ml) => Modloader::from(&ml).unwrap(),
179 //TODO add default modloader to config
180 None => Modloader::Fabric,
181 };
182
183 let ver = match version {
184 Some(ver) => ver,
185 //TODO get latest version
186 //TODO impl config for specific version or latest or latest snap
187 None => "1.19.4".to_string(),
188 };
189
190 list_add(config, id, ver, ml, directory)
191 },
192 ListCommands::Remove { id } => {
193 list_remove(config, id)
194 },
195 ListCommands::List => {
196 todo!()
197 },
198 ListCommands::Change { id } => {
199 list_change(config, id)
200 },
201 ListCommands::Version { id, version, download, remove } => {
202 list_version(config, id, version, download, remove).await
203 }
204 }
42 }, 205 },
43 Cmd::Version => { 206 //TODO a add specific list
44 show_version(); 207 Commands::Update { all, download, clean, remove } => {
45 Ok(()) 208 let mut liststack: Vec<List> = vec![];
209 if all {
210 let list_ids = lists_get_all_ids(config.clone()).unwrap();
211 for id in list_ids {
212 liststack.push(lists_get(config.clone(), id).unwrap());
213 }
214 } else {
215 let current = get_current_list(config.clone()).unwrap();
216 println!("Update list {}:", current.id);
217 liststack.push(current)
218 }
219 update(config, liststack, clean, download, remove).await
46 }, 220 },
47 Cmd::Setup => { 221 //TODO add specific list
48 setup(config).await 222 Commands::Download { all, clean, remove } => {
223 download(config, all, clean, remove).await
49 }, 224 },
50 }.unwrap() 225 Commands::Import { file, download } => {
51} 226 let filestr: String = match file {
227 Some(args) => args,
228 None => devdir(dirs::home_dir().unwrap().join("mlexport.toml").into_os_string().into_string().unwrap().as_str()),
229 };
52 230
53fn show_version() { 231 import(config, filestr, download).await
54 match std::env::var("DEV") {
55 Ok(dev) => {
56 let devint = dev.parse::<i32>().unwrap();
57 if devint >= 1 {
58 println!("Modlist by FxQnLr v{} (DEV)", env!("CARGO_PKG_VERSION"));
59 } else {
60 println!("Modlist by FxQnLr v{}", env!("CARGO_PKG_VERSION"));
61 }
62 }, 232 },
63 Err(..) => println!("Modlist by FxQnLr v{}", env!("CARGO_PKG_VERSION")), 233 Commands::Export { list } => {
64 } 234 export(config, list)
235 },
236 }.unwrap();
65} 237}