summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/apis/modrinth.rs10
-rw-r--r--src/cache.rs3
-rw-r--r--src/commands/download.rs39
-rw-r--r--src/commands/io.rs6
-rw-r--r--src/commands/list.rs4
-rw-r--r--src/commands/modification.rs55
-rw-r--r--src/commands/update.rs56
-rw-r--r--src/config.rs7
-rw-r--r--src/db.rs128
-rw-r--r--src/error.rs8
-rw-r--r--src/files.rs18
-rw-r--r--src/lib.rs14
-rw-r--r--src/main.rs17
13 files changed, 268 insertions, 97 deletions
diff --git a/src/apis/modrinth.rs b/src/apis/modrinth.rs
index fb3952d..9a22633 100644
--- a/src/apis/modrinth.rs
+++ b/src/apis/modrinth.rs
@@ -130,7 +130,10 @@ pub enum GameVersionType {
130 beta, 130 beta,
131} 131}
132 132
133async fn get(api: &str, path: &str) -> Result<Option<Vec<u8>>, Box<dyn std::error::Error>> { 133async fn get(
134 api: &str,
135 path: &str,
136) -> Result<Option<Vec<u8>>, Box<dyn std::error::Error>> {
134 let url = format!(r#"{}{}"#, api, path); 137 let url = format!(r#"{}{}"#, api, path);
135 138
136 let client = Client::builder() 139 let client = Client::builder()
@@ -182,7 +185,10 @@ pub async fn versions(api: &str, id: String, list: List) -> Vec<Version> {
182} 185}
183 186
184///Get version with the version ids 187///Get version with the version ids
185pub async fn get_raw_versions(api: &str, versions: Vec<String>) -> Vec<Version> { 188pub async fn get_raw_versions(
189 api: &str,
190 versions: Vec<String>,
191) -> Vec<Version> {
186 let url = format!(r#"versions?ids=["{}"]"#, versions.join(r#"",""#)); 192 let url = format!(r#"versions?ids=["{}"]"#, versions.join(r#"",""#));
187 193
188 let data = get(api, &url).await.unwrap().unwrap(); 194 let data = get(api, &url).await.unwrap().unwrap();
diff --git a/src/cache.rs b/src/cache.rs
index 1e22091..8df4d2f 100644
--- a/src/cache.rs
+++ b/src/cache.rs
@@ -31,6 +31,7 @@ pub fn get_cached_versions(path: &str) -> HashMap<String, String> {
31/// Panics if . 31/// Panics if .
32pub fn copy_cached_version(version_path: &str, download_path: &str) { 32pub fn copy_cached_version(version_path: &str, download_path: &str) {
33 let versplit: Vec<&str> = version_path.split('/').collect(); 33 let versplit: Vec<&str> = version_path.split('/').collect();
34 let download = format!("{}/{}", download_path, versplit[versplit.len() - 1]); 34 let download =
35 format!("{}/{}", download_path, versplit[versplit.len() - 1]);
35 copy(version_path, download).unwrap(); 36 copy(version_path, download).unwrap();
36} 37}
diff --git a/src/commands/download.rs b/src/commands/download.rs
index dd00ffb..a7cf744 100644
--- a/src/commands/download.rs
+++ b/src/commands/download.rs
@@ -5,7 +5,8 @@ use crate::{
5 db::userlist_get_all_current_versions_with_mods, 5 db::userlist_get_all_current_versions_with_mods,
6 error::{ErrorType, MLError, MLE}, 6 error::{ErrorType, MLError, MLE},
7 files::{ 7 files::{
8 clean_list_dir, delete_version, disable_version, download_versions, get_downloaded_versions, 8 clean_list_dir, delete_version, disable_version, download_versions,
9 get_downloaded_versions,
9 }, 10 },
10 modrinth::get_raw_versions, 11 modrinth::get_raw_versions,
11}; 12};
@@ -18,7 +19,8 @@ pub async fn download(
18 delete_old: bool, 19 delete_old: bool,
19) -> MLE<()> { 20) -> MLE<()> {
20 let mp = MultiProgress::new(); 21 let mp = MultiProgress::new();
21 let download_p = mp.add(ProgressBar::new(liststack.len().try_into().unwrap())); 22 let download_p =
23 mp.add(ProgressBar::new(liststack.len().try_into().unwrap()));
22 download_p.set_style( 24 download_p.set_style(
23 ProgressStyle::with_template(STYLE_BAR_POS) 25 ProgressStyle::with_template(STYLE_BAR_POS)
24 .unwrap() 26 .unwrap()
@@ -28,14 +30,19 @@ pub async fn download(
28 for current_list in liststack { 30 for current_list in liststack {
29 download_p.set_message(format!("Download in {}", current_list.id)); 31 download_p.set_message(format!("Download in {}", current_list.id));
30 32
31 let downloaded_versions = get_downloaded_versions(current_list.clone())?; 33 let downloaded_versions =
32 let current_version_ids = match userlist_get_all_current_versions_with_mods( 34 get_downloaded_versions(current_list.clone())?;
33 config, 35 let current_version_ids =
34 String::from(&current_list.id), 36 match userlist_get_all_current_versions_with_mods(
35 ) { 37 config,
36 Ok(i) => Ok(i), 38 String::from(&current_list.id),
37 Err(e) => Err(MLError::new(ErrorType::DBError, e.to_string().as_str())), 39 ) {
38 }?; 40 Ok(i) => Ok(i),
41 Err(e) => Err(MLError::new(
42 ErrorType::DBError,
43 e.to_string().as_str(),
44 )),
45 }?;
39 46
40 let mut to_download: Vec<String> = vec![]; 47 let mut to_download: Vec<String> = vec![];
41 //(mod_id, version_id) 48 //(mod_id, version_id)
@@ -54,7 +61,10 @@ pub async fn download(
54 .ok_or("SOMETHING_HAS_REALLY_GONE_WRONG") 61 .ok_or("SOMETHING_HAS_REALLY_GONE_WRONG")
55 .unwrap(); 62 .unwrap();
56 if &current_version != downloaded_version { 63 if &current_version != downloaded_version {
57 to_disable.push((mod_id.clone(), String::from(downloaded_version))); 64 to_disable.push((
65 mod_id.clone(),
66 String::from(downloaded_version),
67 ));
58 to_download.push(current_version); 68 to_download.push(current_version);
59 } 69 }
60 } 70 }
@@ -98,7 +108,12 @@ pub async fn download(
98 } else { 108 } else {
99 d_p.set_message(format!("Disable version {}", ver.1)); 109 d_p.set_message(format!("Disable version {}", ver.1));
100 d_p.inc(1); 110 d_p.inc(1);
101 disable_version(config, current_list.clone(), ver.1, ver.0)?; 111 disable_version(
112 config,
113 current_list.clone(),
114 ver.1,
115 ver.0,
116 )?;
102 }; 117 };
103 } 118 }
104 119
diff --git a/src/commands/io.rs b/src/commands/io.rs
index 2501583..8e44b2b 100644
--- a/src/commands/io.rs
+++ b/src/commands/io.rs
@@ -102,7 +102,11 @@ pub fn export(config: &Cfg, list: Option<String>) -> MLE<()> {
102 Ok(()) 102 Ok(())
103} 103}
104 104
105pub async fn import(config: &Cfg, file_str: &str, direct_download: bool) -> MLE<()> { 105pub async fn import(
106 config: &Cfg,
107 file_str: &str,
108 direct_download: bool,
109) -> MLE<()> {
106 let mut file = File::open(file_str)?; 110 let mut file = File::open(file_str)?;
107 let mut content = String::new(); 111 let mut content = String::new();
108 file.read_to_string(&mut content)?; 112 file.read_to_string(&mut content)?;
diff --git a/src/commands/list.rs b/src/commands/list.rs
index b0a082d..3665446 100644
--- a/src/commands/list.rs
+++ b/src/commands/list.rs
@@ -3,8 +3,8 @@ use indicatif::{ProgressBar, ProgressStyle};
3use crate::{ 3use crate::{
4 config::Cfg, 4 config::Cfg,
5 db::{ 5 db::{
6 config_change_current_list, config_get_current_list, lists_get, lists_get_all_ids, 6 config_change_current_list, config_get_current_list, lists_get,
7 lists_insert, lists_remove, lists_version, 7 lists_get_all_ids, lists_insert, lists_remove, lists_version,
8 }, 8 },
9 error::{ErrorType, MLError, MLE}, 9 error::{ErrorType, MLError, MLE},
10 update, Modloader, STYLE_OPERATION, 10 update, Modloader, STYLE_OPERATION,
diff --git a/src/commands/modification.rs b/src/commands/modification.rs
index 577bbd1..4488b70 100644
--- a/src/commands/modification.rs
+++ b/src/commands/modification.rs
@@ -5,12 +5,16 @@ use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
5use crate::{ 5use crate::{
6 config::Cfg, 6 config::Cfg,
7 db::{ 7 db::{
8 lists_get_all_ids, mods_get_id, mods_get_info, mods_insert, mods_remove, 8 lists_get_all_ids, mods_get_id, mods_get_info, mods_insert,
9 userlist_get_all_ids, userlist_get_current_version, userlist_insert, userlist_remove, 9 mods_remove, userlist_get_all_ids, userlist_get_current_version,
10 userlist_insert, userlist_remove,
10 }, 11 },
11 error::{ErrorType, MLError, MLE}, 12 error::{ErrorType, MLError, MLE},
12 files::{delete_version, download_versions}, 13 files::{delete_version, download_versions},
13 modrinth::{extract_current_version, get_raw_versions, project, projects, versions, Version}, 14 modrinth::{
15 extract_current_version, get_raw_versions, project, projects, versions,
16 Version,
17 },
14 List, PROGRESS_CHARS, STYLE_BAR_POS, STYLE_OPERATION, 18 List, PROGRESS_CHARS, STYLE_BAR_POS, STYLE_OPERATION,
15}; 19};
16 20
@@ -60,7 +64,9 @@ pub async fn mod_add(
60 for m in mods { 64 for m in mods {
61 add_p.inc(1); 65 add_p.inc(1);
62 match m.id { 66 match m.id {
63 IDSelector::ModificationID(pid) => mod_ids.push((pid, m.set_version)), 67 IDSelector::ModificationID(pid) => {
68 mod_ids.push((pid, m.set_version))
69 }
64 IDSelector::VersionID(vid) => ver_ids.push((vid, m.set_version)), 70 IDSelector::VersionID(vid) => ver_ids.push((vid, m.set_version)),
65 } 71 }
66 } 72 }
@@ -69,7 +75,8 @@ pub async fn mod_add(
69 75
70 let mut projectinfo: Vec<ProjectInfo> = Vec::new(); 76 let mut projectinfo: Vec<ProjectInfo> = Vec::new();
71 if !mod_ids.is_empty() { 77 if !mod_ids.is_empty() {
72 projectinfo.append(&mut get_mod_infos(config, mod_ids, list.clone()).await?); 78 projectinfo
79 .append(&mut get_mod_infos(config, mod_ids, list.clone()).await?);
73 }; 80 };
74 if !ver_ids.is_empty() { 81 if !ver_ids.is_empty() {
75 projectinfo.append(&mut get_ver_info(config, ver_ids).await?); 82 projectinfo.append(&mut get_ver_info(config, ver_ids).await?);
@@ -113,7 +120,10 @@ pub async fn mod_add(
113 project.set_version, 120 project.set_version,
114 ) { 121 ) {
115 Err(e) => { 122 Err(e) => {
116 let expected_err = format!("SQL: UNIQUE constraint failed: {}.mod_id", list.id); 123 let expected_err = format!(
124 "SQL: UNIQUE constraint failed: {}.mod_id",
125 list.id
126 );
117 if e.to_string() == expected_err { 127 if e.to_string() == expected_err {
118 Err(MLError::new( 128 Err(MLError::new(
119 ErrorType::ModError, 129 ErrorType::ModError,
@@ -126,7 +136,12 @@ pub async fn mod_add(
126 Ok(..) => Ok(..), 136 Ok(..) => Ok(..),
127 }?; 137 }?;
128 138
129 match mods_insert(config, &project.mod_id, &project.slug, &project.title) { 139 match mods_insert(
140 config,
141 &project.mod_id,
142 &project.slug,
143 &project.title,
144 ) {
130 Err(e) => { 145 Err(e) => {
131 if e.to_string() == "SQL: UNIQUE constraint failed: mods.id" { 146 if e.to_string() == "SQL: UNIQUE constraint failed: mods.id" {
132 Ok(..) 147 Ok(..)
@@ -149,7 +164,14 @@ pub async fn mod_add(
149 //Download all the added mods 164 //Download all the added mods
150 if direct_download { 165 if direct_download {
151 add_p.set_message("Download mods"); 166 add_p.set_message("Download mods");
152 download_versions(list.clone(), config.clone(), downloadstack, &mp, &add_p).await?; 167 download_versions(
168 list.clone(),
169 config.clone(),
170 downloadstack,
171 &mp,
172 &add_p,
173 )
174 .await?;
153 }; 175 };
154 176
155 add_p.finish_with_message("Added all mods"); 177 add_p.finish_with_message("Added all mods");
@@ -191,7 +213,8 @@ async fn get_mod_infos(
191 let current_version: Option<Version>; 213 let current_version: Option<Version>;
192 let file: String; 214 let file: String;
193 if !available_versions.is_empty() { 215 if !available_versions.is_empty() {
194 let current_id = extract_current_version(available_versions.clone())?; 216 let current_id =
217 extract_current_version(available_versions.clone())?;
195 218
196 current_version = Some( 219 current_version = Some(
197 available_versions 220 available_versions
@@ -242,7 +265,10 @@ async fn get_mod_infos(
242 Ok(projectinfo) 265 Ok(projectinfo)
243} 266}
244 267
245async fn get_ver_info(config: &Cfg, ver_ids: Vec<(String, bool)>) -> MLE<Vec<ProjectInfo>> { 268async fn get_ver_info(
269 config: &Cfg,
270 ver_ids: Vec<(String, bool)>,
271) -> MLE<Vec<ProjectInfo>> {
246 let mut setmap: HashMap<String, bool> = HashMap::new(); 272 let mut setmap: HashMap<String, bool> = HashMap::new();
247 273
248 let mut ids = vec![]; 274 let mut ids = vec![];
@@ -311,7 +337,9 @@ pub fn mod_remove(config: &Cfg, id: &str, list: &List) -> MLE<()> {
311 match delete_version(list, version) { 337 match delete_version(list, version) {
312 Ok(_) => (), 338 Ok(_) => (),
313 Err(err) => { 339 Err(err) => {
314 if err.to_string() != "User input not accepted: VERSION_NOT_FOUND_IN_FILES" { 340 if err.to_string()
341 != "User input not accepted: VERSION_NOT_FOUND_IN_FILES"
342 {
315 return Err(err); 343 return Err(err);
316 }; 344 };
317 } 345 }
@@ -343,7 +371,10 @@ pub fn mod_remove(config: &Cfg, id: &str, list: &List) -> MLE<()> {
343 mods_remove(config, &mod_id)?; 371 mods_remove(config, &mod_id)?;
344 }; 372 };
345 373
346 progress.finish_with_message(format!("Removed {} from {}", info.title, list.id)); 374 progress.finish_with_message(format!(
375 "Removed {} from {}",
376 info.title, list.id
377 ));
347 378
348 Ok(()) 379 Ok(())
349} 380}
diff --git a/src/commands/update.rs b/src/commands/update.rs
index 3aae002..c19c02c 100644
--- a/src/commands/update.rs
+++ b/src/commands/update.rs
@@ -4,10 +4,13 @@ use crate::{
4 config::Cfg, 4 config::Cfg,
5 db::{ 5 db::{
6 mods_get_info, userlist_change_versions, userlist_get_all_ids, 6 mods_get_info, userlist_change_versions, userlist_get_all_ids,
7 userlist_get_applicable_versions, userlist_get_current_version, userlist_get_set_version, 7 userlist_get_applicable_versions, userlist_get_current_version,
8 userlist_get_set_version,
8 }, 9 },
9 error::{ErrorType, MLError, MLE}, 10 error::{ErrorType, MLError, MLE},
10 files::{clean_list_dir, delete_version, disable_version, download_versions}, 11 files::{
12 clean_list_dir, delete_version, disable_version, download_versions,
13 },
11 modrinth::{extract_current_version, versions, Version}, 14 modrinth::{extract_current_version, versions, Version},
12 List, PROGRESS_CHARS, STYLE_BAR_POS, STYLE_OPERATION, 15 List, PROGRESS_CHARS, STYLE_BAR_POS, STYLE_OPERATION,
13}; 16};
@@ -21,7 +24,8 @@ pub async fn update(
21) -> MLE<()> { 24) -> MLE<()> {
22 let mp = MultiProgress::new(); 25 let mp = MultiProgress::new();
23 26
24 let update_p = mp.add(ProgressBar::new(liststack.len().try_into().unwrap())); 27 let update_p =
28 mp.add(ProgressBar::new(liststack.len().try_into().unwrap()));
25 update_p.set_style( 29 update_p.set_style(
26 ProgressStyle::with_template(STYLE_BAR_POS) 30 ProgressStyle::with_template(STYLE_BAR_POS)
27 .unwrap() 31 .unwrap()
@@ -32,12 +36,16 @@ pub async fn update(
32 update_p.set_message(format!("Update {}", current_list.id)); 36 update_p.set_message(format!("Update {}", current_list.id));
33 37
34 let list_p = mp.insert_before(&update_p, ProgressBar::new(2)); 38 let list_p = mp.insert_before(&update_p, ProgressBar::new(2));
35 list_p.set_style(ProgressStyle::with_template(STYLE_OPERATION).unwrap()); 39 list_p
40 .set_style(ProgressStyle::with_template(STYLE_OPERATION).unwrap());
36 list_p.set_message("Update mods"); 41 list_p.set_message("Update mods");
37 42
38 let mods = userlist_get_all_ids(config, &current_list.id)?; 43 let mods = userlist_get_all_ids(config, &current_list.id)?;
39 44
40 let list_u_p = mp.insert_before(&list_p, ProgressBar::new(mods.len().try_into().unwrap())); 45 let list_u_p = mp.insert_before(
46 &list_p,
47 ProgressBar::new(mods.len().try_into().unwrap()),
48 );
41 list_u_p.set_style( 49 list_u_p.set_style(
42 ProgressStyle::with_template(STYLE_BAR_POS) 50 ProgressStyle::with_template(STYLE_BAR_POS)
43 .unwrap() 51 .unwrap()
@@ -58,10 +66,19 @@ pub async fn update(
58 } 66 }
59 67
60 //Getting current installed version for disable or delete 68 //Getting current installed version for disable or delete
61 let disable_version = userlist_get_current_version(config, &current_list.id, &id)?; 69 let disable_version =
70 userlist_get_current_version(config, &current_list.id, &id)?;
62 71
63 updatestack.push( 72 updatestack.push(
64 match specific_update(config, clean, current_list.clone(), &id, &list_u_p).await { 73 match specific_update(
74 config,
75 clean,
76 current_list.clone(),
77 &id,
78 &list_u_p,
79 )
80 .await
81 {
65 Ok(ver) => { 82 Ok(ver) => {
66 current_versions.push((disable_version, id)); 83 current_versions.push((disable_version, id));
67 ver 84 ver
@@ -79,7 +96,10 @@ pub async fn update(
79 list_u_p.inc(1); 96 list_u_p.inc(1);
80 } 97 }
81 98
82 list_u_p.finish_with_message(format!("Updated mods in {}", current_list.id)); 99 list_u_p.finish_with_message(format!(
100 "Updated mods in {}",
101 current_list.id
102 ));
83 103
84 if clean { 104 if clean {
85 list_p.set_message("Cleaning"); 105 list_p.set_message("Cleaning");
@@ -100,7 +120,9 @@ pub async fn update(
100 if !clean { 120 if !clean {
101 let d_p = mp.insert_before( 121 let d_p = mp.insert_before(
102 &list_p, 122 &list_p,
103 ProgressBar::new(current_versions.len().try_into().unwrap()), 123 ProgressBar::new(
124 current_versions.len().try_into().unwrap(),
125 ),
104 ); 126 );
105 d_p.set_style( 127 d_p.set_style(
106 ProgressStyle::with_template(STYLE_BAR_POS) 128 ProgressStyle::with_template(STYLE_BAR_POS)
@@ -115,7 +137,12 @@ pub async fn update(
115 } else if ver.0 != "NONE" { 137 } else if ver.0 != "NONE" {
116 d_p.set_message(format!("Disable version {}", ver.0)); 138 d_p.set_message(format!("Disable version {}", ver.0));
117 d_p.inc(1); 139 d_p.inc(1);
118 disable_version(config, current_list.clone(), ver.0, ver.1)?; 140 disable_version(
141 config,
142 current_list.clone(),
143 ver.0,
144 ver.1,
145 )?;
119 }; 146 };
120 } 147 }
121 148
@@ -144,7 +171,8 @@ async fn specific_update(
144 id: &str, 171 id: &str,
145 progress: &ProgressBar, 172 progress: &ProgressBar,
146) -> MLE<Version> { 173) -> MLE<Version> {
147 let applicable_versions = versions(&config.apis.modrinth, String::from(id), list.clone()).await; 174 let applicable_versions =
175 versions(&config.apis.modrinth, String::from(id), list.clone()).await;
148 176
149 let mut versions: Vec<String> = vec![]; 177 let mut versions: Vec<String> = vec![];
150 178
@@ -159,7 +187,11 @@ async fn specific_update(
159 let mut current: Vec<Version> = vec![]; 187 let mut current: Vec<Version> = vec![];
160 if clean 188 if clean
161 || (versions.join("|") 189 || (versions.join("|")
162 != userlist_get_applicable_versions(config, String::from(&list.id), String::from(id))?) 190 != userlist_get_applicable_versions(
191 config,
192 String::from(&list.id),
193 String::from(id),
194 )?)
163 { 195 {
164 let current_str = extract_current_version(applicable_versions.clone())?; 196 let current_str = extract_current_version(applicable_versions.clone())?;
165 197
diff --git a/src/config.rs b/src/config.rs
index 3858484..f0eb8f7 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -7,7 +7,9 @@ use std::{
7use indicatif::{ProgressBar, ProgressStyle}; 7use indicatif::{ProgressBar, ProgressStyle};
8use serde::{Deserialize, Serialize}; 8use serde::{Deserialize, Serialize};
9 9
10use crate::{check_game_versions, db::db_setup, error::MLE, Modloader, VersionLevel}; 10use crate::{
11 check_game_versions, db::db_setup, error::MLE, Modloader, VersionLevel,
12};
11 13
12#[derive(Debug, Clone, Serialize, Deserialize)] 14#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct Cfg { 15pub struct Cfg {
@@ -44,7 +46,8 @@ impl Cfg {
44 let mut file = match File::open(&configfile) { 46 let mut file = match File::open(&configfile) {
45 Ok(file) => file, 47 Ok(file) => file,
46 Err(err) => { 48 Err(err) => {
47 if err.kind() == std::io::ErrorKind::NotFound && path.is_none() { 49 if err.kind() == std::io::ErrorKind::NotFound && path.is_none()
50 {
48 create_config(&configfile)?; 51 create_config(&configfile)?;
49 File::open(&configfile)? 52 File::open(&configfile)?
50 } else { 53 } else {
diff --git a/src/db.rs b/src/db.rs
index 1958fc5..49db2fd 100644
--- a/src/db.rs
+++ b/src/db.rs
@@ -21,7 +21,9 @@ pub fn mods_insert(config: &Cfg, id: &str, slug: &str, name: &str) -> MLE<()> {
21 Ok(()) 21 Ok(())
22} 22}
23 23
24pub fn mods_get_all_ids(config: &Cfg) -> Result<Vec<String>, Box<dyn std::error::Error>> { 24pub fn mods_get_all_ids(
25 config: &Cfg,
26) -> Result<Vec<String>, Box<dyn std::error::Error>> {
25 let data = format!("{}/data.db", config.data); 27 let data = format!("{}/data.db", config.data);
26 let connection = Connection::open(data).unwrap(); 28 let connection = Connection::open(data).unwrap();
27 29
@@ -64,8 +66,10 @@ pub fn mods_get_id(data: &str, slug: &str) -> MLE<String> {
64 } 66 }
65 //get from id if no slug found 67 //get from id if no slug found
66 if mod_id.is_empty() { 68 if mod_id.is_empty() {
67 let mut stmt = connection.prepare("SELECT id FROM mods WHERE id = ?")?; 69 let mut stmt =
68 let id_iter = stmt.query_map([slug], |row| row.get::<usize, String>(0))?; 70 connection.prepare("SELECT id FROM mods WHERE id = ?")?;
71 let id_iter =
72 stmt.query_map([slug], |row| row.get::<usize, String>(0))?;
69 73
70 for id in id_iter { 74 for id in id_iter {
71 mod_id = id?; 75 mod_id = id?;
@@ -73,8 +77,10 @@ pub fn mods_get_id(data: &str, slug: &str) -> MLE<String> {
73 } 77 }
74 //get from title if no id found from slug 78 //get from title if no id found from slug
75 if mod_id.is_empty() { 79 if mod_id.is_empty() {
76 let mut stmt = connection.prepare("SELECT id FROM mods WHERE title = ?")?; 80 let mut stmt =
77 let id_iter = stmt.query_map([slug], |row| row.get::<usize, String>(0))?; 81 connection.prepare("SELECT id FROM mods WHERE title = ?")?;
82 let id_iter =
83 stmt.query_map([slug], |row| row.get::<usize, String>(0))?;
78 84
79 for id in id_iter { 85 for id in id_iter {
80 mod_id = id?; 86 mod_id = id?;
@@ -98,7 +104,8 @@ pub fn mods_get_info(config: &Cfg, id: &str) -> MLE<ModInfo> {
98 let connection = Connection::open(data)?; 104 let connection = Connection::open(data)?;
99 105
100 let mut mod_info: Option<ModInfo> = None; 106 let mut mod_info: Option<ModInfo> = None;
101 let mut stmt = connection.prepare("SELECT title, slug FROM mods WHERE id = ?")?; 107 let mut stmt =
108 connection.prepare("SELECT title, slug FROM mods WHERE id = ?")?;
102 let name_iter = stmt.query_map([id], |row| { 109 let name_iter = stmt.query_map([id], |row| {
103 Ok(vec![ 110 Ok(vec![
104 row.get::<usize, String>(0)?, 111 row.get::<usize, String>(0)?,
@@ -135,7 +142,10 @@ pub struct DBModlistVersions {
135 pub versions: String, 142 pub versions: String,
136} 143}
137 144
138pub fn mods_get_versions(config: &Cfg, mods: Vec<String>) -> MLE<Vec<DBModlistVersions>> { 145pub fn mods_get_versions(
146 config: &Cfg,
147 mods: Vec<String>,
148) -> MLE<Vec<DBModlistVersions>> {
139 let data = format!("{}/data.db", config.data); 149 let data = format!("{}/data.db", config.data);
140 let connection = Connection::open(data)?; 150 let connection = Connection::open(data)?;
141 151
@@ -153,8 +163,9 @@ pub fn mods_get_versions(config: &Cfg, mods: Vec<String>) -> MLE<Vec<DBModlistVe
153 } 163 }
154 164
155 let mut versionmaps: Vec<DBModlistVersions> = Vec::new(); 165 let mut versionmaps: Vec<DBModlistVersions> = Vec::new();
156 let mut stmt = connection 166 let mut stmt = connection.prepare(
157 .prepare(format!("SELECT id, versions, title FROM mods {}", wherestr).as_str())?; 167 format!("SELECT id, versions, title FROM mods {}", wherestr).as_str(),
168 )?;
158 let id_iter = stmt.query_map([], |row| { 169 let id_iter = stmt.query_map([], |row| {
159 Ok(vec![ 170 Ok(vec![
160 row.get::<usize, String>(0)?, 171 row.get::<usize, String>(0)?,
@@ -218,7 +229,8 @@ pub fn userlist_get_all_ids(config: &Cfg, list_id: &str) -> MLE<Vec<String>> {
218 let connection = Connection::open(data).unwrap(); 229 let connection = Connection::open(data).unwrap();
219 230
220 let mut mod_ids: Vec<String> = Vec::new(); 231 let mut mod_ids: Vec<String> = Vec::new();
221 let mut stmt = connection.prepare(format!("SELECT mod_id FROM {}", list_id).as_str())?; 232 let mut stmt = connection
233 .prepare(format!("SELECT mod_id FROM {}", list_id).as_str())?;
222 let id_iter = stmt.query_map([], |row| row.get::<usize, String>(0))?; 234 let id_iter = stmt.query_map([], |row| row.get::<usize, String>(0))?;
223 235
224 for id in id_iter { 236 for id in id_iter {
@@ -261,7 +273,8 @@ pub fn userlist_get_applicable_versions(
261 ) 273 )
262 .as_str(), 274 .as_str(),
263 )?; 275 )?;
264 let ver_iter = stmt.query_map([mod_id], |row| row.get::<usize, String>(0))?; 276 let ver_iter =
277 stmt.query_map([mod_id], |row| row.get::<usize, String>(0))?;
265 278
266 for ver in ver_iter { 279 for ver in ver_iter {
267 version = ver?; 280 version = ver?;
@@ -281,8 +294,9 @@ pub fn userlist_get_all_applicable_versions_with_mods(
281 let connection = Connection::open(data)?; 294 let connection = Connection::open(data)?;
282 295
283 let mut versions: Vec<(String, String)> = Vec::new(); 296 let mut versions: Vec<(String, String)> = Vec::new();
284 let mut stmt = connection 297 let mut stmt = connection.prepare(
285 .prepare(format!("SELECT mod_id, applicable_versions FROM {}", list_id).as_str())?; 298 format!("SELECT mod_id, applicable_versions FROM {}", list_id).as_str(),
299 )?;
286 let id_iter = stmt.query_map([], |row| { 300 let id_iter = stmt.query_map([], |row| {
287 Ok(vec![ 301 Ok(vec![
288 row.get::<usize, String>(0)?, 302 row.get::<usize, String>(0)?,
@@ -302,14 +316,21 @@ pub fn userlist_get_all_applicable_versions_with_mods(
302 Ok(versions) 316 Ok(versions)
303} 317}
304 318
305pub fn userlist_get_current_version(config: &Cfg, list_id: &str, mod_id: &str) -> MLE<String> { 319pub fn userlist_get_current_version(
320 config: &Cfg,
321 list_id: &str,
322 mod_id: &str,
323) -> MLE<String> {
306 let data = format!("{}/data.db", config.data); 324 let data = format!("{}/data.db", config.data);
307 let connection = Connection::open(data).unwrap(); 325 let connection = Connection::open(data).unwrap();
308 326
309 let mut version: String = String::new(); 327 let mut version: String = String::new();
310 let mut stmt = connection 328 let mut stmt = connection.prepare(
311 .prepare(format!("SELECT current_version FROM {} WHERE mod_id = ?", list_id).as_str())?; 329 format!("SELECT current_version FROM {} WHERE mod_id = ?", list_id)
312 let ver_iter = stmt.query_map([&mod_id], |row| row.get::<usize, String>(0))?; 330 .as_str(),
331 )?;
332 let ver_iter =
333 stmt.query_map([&mod_id], |row| row.get::<usize, String>(0))?;
313 334
314 for ver in ver_iter { 335 for ver in ver_iter {
315 version = ver?; 336 version = ver?;
@@ -321,13 +342,16 @@ pub fn userlist_get_current_version(config: &Cfg, list_id: &str, mod_id: &str) -
321 } 342 }
322} 343}
323 344
324pub fn userlist_get_all_current_version_ids(config: &Cfg, list_id: String) -> MLE<Vec<String>> { 345pub fn userlist_get_all_current_version_ids(
346 config: &Cfg,
347 list_id: String,
348) -> MLE<Vec<String>> {
325 let data = format!("{}/data.db", config.data); 349 let data = format!("{}/data.db", config.data);
326 let connection = Connection::open(data)?; 350 let connection = Connection::open(data)?;
327 351
328 let mut versions: Vec<String> = Vec::new(); 352 let mut versions: Vec<String> = Vec::new();
329 let mut stmt = 353 let mut stmt = connection
330 connection.prepare(format!("SELECT current_version FROM {}", list_id).as_str())?; 354 .prepare(format!("SELECT current_version FROM {}", list_id).as_str())?;
331 let id_iter = stmt.query_map([], |row| row.get::<usize, String>(0))?; 355 let id_iter = stmt.query_map([], |row| row.get::<usize, String>(0))?;
332 356
333 for id in id_iter { 357 for id in id_iter {
@@ -349,8 +373,9 @@ pub fn userlist_get_all_current_versions_with_mods(
349 let connection = Connection::open(data)?; 373 let connection = Connection::open(data)?;
350 374
351 let mut versions: Vec<(String, String)> = Vec::new(); 375 let mut versions: Vec<(String, String)> = Vec::new();
352 let mut stmt = 376 let mut stmt = connection.prepare(
353 connection.prepare(format!("SELECT mod_id, current_version FROM {}", list_id).as_str())?; 377 format!("SELECT mod_id, current_version FROM {}", list_id).as_str(),
378 )?;
354 let id_iter = stmt.query_map([], |row| { 379 let id_iter = stmt.query_map([], |row| {
355 Ok(vec![ 380 Ok(vec![
356 row.get::<usize, String>(0)?, 381 row.get::<usize, String>(0)?,
@@ -373,14 +398,21 @@ pub fn userlist_get_all_current_versions_with_mods(
373 Ok(versions) 398 Ok(versions)
374} 399}
375 400
376pub fn userlist_get_set_version(config: &Cfg, list_id: &str, mod_id: &str) -> MLE<bool> { 401pub fn userlist_get_set_version(
402 config: &Cfg,
403 list_id: &str,
404 mod_id: &str,
405) -> MLE<bool> {
377 let data = format!("{}/data.db", config.data); 406 let data = format!("{}/data.db", config.data);
378 let connection = Connection::open(data).unwrap(); 407 let connection = Connection::open(data).unwrap();
379 408
380 let mut set_version: bool = false; 409 let mut set_version: bool = false;
381 let mut stmt = connection 410 let mut stmt = connection.prepare(
382 .prepare(format!("SELECT set_version FROM {} WHERE mod_id = ?", list_id).as_str())?; 411 format!("SELECT set_version FROM {} WHERE mod_id = ?", list_id)
383 let ver_iter = stmt.query_map([&mod_id], |row| row.get::<usize, bool>(0))?; 412 .as_str(),
413 )?;
414 let ver_iter =
415 stmt.query_map([&mod_id], |row| row.get::<usize, bool>(0))?;
384 416
385 for ver in ver_iter { 417 for ver in ver_iter {
386 set_version = ver?; 418 set_version = ver?;
@@ -413,11 +445,16 @@ pub fn userlist_add_disabled_versions(
413 let data = format!("{}/data.db", config.data); 445 let data = format!("{}/data.db", config.data);
414 let connection = Connection::open(data)?; 446 let connection = Connection::open(data)?;
415 447
416 let currently_disabled_versions = 448 let currently_disabled_versions = userlist_get_disabled_versions(
417 userlist_get_disabled_versions(config, String::from(&list_id), String::from(&mod_id))?; 449 config,
450 String::from(&list_id),
451 String::from(&mod_id),
452 )?;
418 let disabled_versions = match currently_disabled_versions == "NONE" { 453 let disabled_versions = match currently_disabled_versions == "NONE" {
419 true => disabled_version, 454 true => disabled_version,
420 false => format!("{}|{}", currently_disabled_versions, disabled_version), 455 false => {
456 format!("{}|{}", currently_disabled_versions, disabled_version)
457 }
421 }; 458 };
422 459
423 connection.execute( 460 connection.execute(
@@ -440,9 +477,12 @@ pub fn userlist_get_disabled_versions(
440 let connection = Connection::open(data).unwrap(); 477 let connection = Connection::open(data).unwrap();
441 478
442 let mut version: String = String::new(); 479 let mut version: String = String::new();
443 let mut stmt = connection 480 let mut stmt = connection.prepare(
444 .prepare(format!("SELECT disabled_versions FROM {} WHERE mod_id = ?", list_id).as_str())?; 481 format!("SELECT disabled_versions FROM {} WHERE mod_id = ?", list_id)
445 let ver_iter = stmt.query_map([mod_id], |row| row.get::<usize, String>(0))?; 482 .as_str(),
483 )?;
484 let ver_iter =
485 stmt.query_map([mod_id], |row| row.get::<usize, String>(0))?;
446 486
447 for ver in ver_iter { 487 for ver in ver_iter {
448 version = ver?; 488 version = ver?;
@@ -462,8 +502,9 @@ pub fn userlist_get_all_downloads(
462 let connection = Connection::open(data).unwrap(); 502 let connection = Connection::open(data).unwrap();
463 503
464 let mut links: Vec<String> = Vec::new(); 504 let mut links: Vec<String> = Vec::new();
465 let mut stmt = 505 let mut stmt = connection.prepare(
466 connection.prepare(format!("SELECT current_download FROM {}", list_id).as_str())?; 506 format!("SELECT current_download FROM {}", list_id).as_str(),
507 )?;
467 let link_iter = stmt.query_map([], |row| row.get::<usize, String>(0))?; 508 let link_iter = stmt.query_map([], |row| row.get::<usize, String>(0))?;
468 509
469 for link in link_iter { 510 for link in link_iter {
@@ -521,8 +562,9 @@ pub fn lists_get(config: &Cfg, list_id: &str) -> MLE<List> {
521 modloader: Modloader::Fabric, 562 modloader: Modloader::Fabric,
522 download_folder: String::new(), 563 download_folder: String::new(),
523 }; 564 };
524 let mut stmt = connection 565 let mut stmt = connection.prepare(
525 .prepare("SELECT mc_version, modloader, download_folder FROM lists WHERE id = ?")?; 566 "SELECT mc_version, modloader, download_folder FROM lists WHERE id = ?",
567 )?;
526 568
527 let list_iter = stmt.query_map([&list_id], |row| { 569 let list_iter = stmt.query_map([&list_id], |row| {
528 Ok(vec![ 570 Ok(vec![
@@ -595,7 +637,8 @@ pub fn config_get_current_list(config: &Cfg) -> MLE<String> {
595 let connection = Connection::open(data).unwrap(); 637 let connection = Connection::open(data).unwrap();
596 638
597 let mut list_id = String::new(); 639 let mut list_id = String::new();
598 let mut stmt = connection.prepare("SELECT value FROM user_config WHERE id = 'current_list'")?; 640 let mut stmt = connection
641 .prepare("SELECT value FROM user_config WHERE id = 'current_list'")?;
599 let list_iter = stmt.query_map([], |row| row.get::<usize, String>(0))?; 642 let list_iter = stmt.query_map([], |row| row.get::<usize, String>(0))?;
600 643
601 for list in list_iter { 644 for list in list_iter {
@@ -630,7 +673,9 @@ pub fn s_userlist_update_download(
630 Ok(()) 673 Ok(())
631} 674}
632 675
633pub fn s_config_create_version(config: &Cfg) -> Result<(), Box<dyn std::error::Error>> { 676pub fn s_config_create_version(
677 config: &Cfg,
678) -> Result<(), Box<dyn std::error::Error>> {
634 let data = format!("{}/data.db", config.data); 679 let data = format!("{}/data.db", config.data);
635 let connection = Connection::open(data)?; 680 let connection = Connection::open(data)?;
636 681
@@ -655,12 +700,15 @@ pub fn s_config_update_version(
655 Ok(()) 700 Ok(())
656} 701}
657 702
658pub fn s_config_get_version(config: &Cfg) -> Result<String, Box<dyn std::error::Error>> { 703pub fn s_config_get_version(
704 config: &Cfg,
705) -> Result<String, Box<dyn std::error::Error>> {
659 let data = format!("{}/data.db", config.data); 706 let data = format!("{}/data.db", config.data);
660 let connection = Connection::open(data)?; 707 let connection = Connection::open(data)?;
661 708
662 let mut version: String = String::new(); 709 let mut version: String = String::new();
663 let mut stmt = connection.prepare("SELECT value FROM user_config WHERE id = 'db_version'")?; 710 let mut stmt = connection
711 .prepare("SELECT value FROM user_config WHERE id = 'db_version'")?;
664 let ver_iter = stmt.query_map([], |row| row.get::<usize, String>(0))?; 712 let ver_iter = stmt.query_map([], |row| row.get::<usize, String>(0))?;
665 713
666 for ver in ver_iter { 714 for ver in ver_iter {
diff --git a/src/error.rs b/src/error.rs
index f981f14..a2b37a8 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -34,8 +34,12 @@ impl std::error::Error for MLError {
34impl fmt::Display for MLError { 34impl fmt::Display for MLError {
35 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 35 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
36 match self.etype { 36 match self.etype {
37 ErrorType::ArgumentError => write!(f, "User input not accepted: {}", self.message), 37 ErrorType::ArgumentError => {
38 ErrorType::ArgumentCountError => write!(f, "Too many/too few arguments"), 38 write!(f, "User input not accepted: {}", self.message)
39 }
40 ErrorType::ArgumentCountError => {
41 write!(f, "Too many/too few arguments")
42 }
39 ErrorType::ConfigError => write!(f, "CONFIG"), 43 ErrorType::ConfigError => write!(f, "CONFIG"),
40 ErrorType::DBError => write!(f, "Database: {}", self.message), 44 ErrorType::DBError => write!(f, "Database: {}", self.message),
41 ErrorType::ModError => write!(f, "Mod: {}", self.message), 45 ErrorType::ModError => write!(f, "Mod: {}", self.message),
diff --git a/src/files.rs b/src/files.rs
index c81857b..3a16c62 100644
--- a/src/files.rs
+++ b/src/files.rs
@@ -92,7 +92,9 @@ async fn download_version(
92 let mut splitname: Vec<&str> = file.filename.split('.').collect(); 92 let mut splitname: Vec<&str> = file.filename.split('.').collect();
93 let extension = match splitname.pop().ok_or("") { 93 let extension = match splitname.pop().ok_or("") {
94 Ok(e) => e, 94 Ok(e) => e,
95 Err(..) => return Err(MLError::new(ErrorType::Other, "NO_FILE_EXTENSION")), 95 Err(..) => {
96 return Err(MLError::new(ErrorType::Other, "NO_FILE_EXTENSION"))
97 }
96 }; 98 };
97 let filename = format!( 99 let filename = format!(
98 "{}.mr.{}.{}.{}", 100 "{}.mr.{}.{}.{}",
@@ -102,7 +104,8 @@ async fn download_version(
102 extension 104 extension
103 ); 105 );
104 106
105 download_file(&file.url, &list.download_folder, &filename, &progress).await?; 107 download_file(&file.url, &list.download_folder, &filename, &progress)
108 .await?;
106 109
107 progress.set_message(format!("Copy {} to cache", version.id)); 110 progress.set_message(format!("Copy {} to cache", version.id));
108 let dl_path_file = format!("{}/{}", list.download_folder, filename); 111 let dl_path_file = format!("{}/{}", list.download_folder, filename);
@@ -119,7 +122,12 @@ async fn download_version(
119 Ok(()) 122 Ok(())
120} 123}
121 124
122async fn download_file(url: &str, path: &str, name: &str, progress: &ProgressBar) -> MLE<()> { 125async fn download_file(
126 url: &str,
127 path: &str,
128 name: &str,
129 progress: &ProgressBar,
130) -> MLE<()> {
123 let dl_path_file = format!("{}/{}", path, name); 131 let dl_path_file = format!("{}/{}", path, name);
124 let res = Client::new().get(url).send().await?; 132 let res = Client::new().get(url).send().await?;
125 133
@@ -185,7 +193,9 @@ pub fn get_file_path(list: &List, versionid: String) -> MLE<String> {
185 if path.is_file() { 193 if path.is_file() {
186 let pathstr = match path.to_str().ok_or("") { 194 let pathstr = match path.to_str().ok_or("") {
187 Ok(s) => s, 195 Ok(s) => s,
188 Err(..) => return Err(MLError::new(ErrorType::Other, "INVALID_PATH")), 196 Err(..) => {
197 return Err(MLError::new(ErrorType::Other, "INVALID_PATH"))
198 }
189 }; 199 };
190 let namesplit: Vec<&str> = pathstr.split('.').collect(); 200 let namesplit: Vec<&str> = pathstr.split('.').collect();
191 let ver_id = namesplit[namesplit.len() - 2]; 201 let ver_id = namesplit[namesplit.len() - 2];
diff --git a/src/lib.rs b/src/lib.rs
index d76f8bf..f77befc 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -44,7 +44,9 @@ impl Modloader {
44 "forge" => Ok(Modloader::Forge), 44 "forge" => Ok(Modloader::Forge),
45 "fabric" => Ok(Modloader::Fabric), 45 "fabric" => Ok(Modloader::Fabric),
46 "quilt" => Ok(Modloader::Quilt), 46 "quilt" => Ok(Modloader::Quilt),
47 _ => Err(MLError::new(ErrorType::ArgumentError, "UNKNOWN_MODLOADER")), 47 _ => {
48 Err(MLError::new(ErrorType::ArgumentError, "UNKNOWN_MODLOADER"))
49 }
48 } 50 }
49 } 51 }
50} 52}
@@ -76,7 +78,9 @@ pub async fn check_game_versions(path: &str, force: bool) -> MLE<()> {
76 p.set_message("Update minecraft versions"); 78 p.set_message("Update minecraft versions");
77 79
78 let creation_time = fs::metadata(path)?.created()?; 80 let creation_time = fs::metadata(path)?.created()?;
79 if !force && creation_time.elapsed().unwrap() < Duration::from_secs(60 * 60 * 24) { 81 if !force
82 && creation_time.elapsed().unwrap() < Duration::from_secs(60 * 60 * 24)
83 {
80 return Ok(()); 84 return Ok(());
81 } 85 }
82 86
@@ -107,7 +111,11 @@ impl VersionLevel {
107 } 111 }
108 } 112 }
109 113
110 pub async fn get(self, versions_path: &str, force_update: bool) -> MLE<String> { 114 pub async fn get(
115 self,
116 versions_path: &str,
117 force_update: bool,
118 ) -> MLE<String> {
111 let path = format!("{}/versions.json", versions_path); 119 let path = format!("{}/versions.json", versions_path);
112 check_game_versions(&path, force_update).await?; 120 check_game_versions(&path, force_update).await?;
113 let mut versions = load_game_versions(&path)?.into_iter(); 121 let mut versions = load_game_versions(&path)?.into_iter();
diff --git a/src/main.rs b/src/main.rs
index d9ad6af..5d60a17 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -2,8 +2,9 @@ use clap::{Parser, Subcommand};
2use modlist::{ 2use modlist::{
3 config::Cfg, 3 config::Cfg,
4 db::{config_get_current_list, lists_get, lists_get_all_ids}, 4 db::{config_get_current_list, lists_get, lists_get_all_ids},
5 download, export, get_current_list, import, list_add, list_change, list_list, list_remove, 5 download, export, get_current_list, import, list_add, list_change,
6 list_version, mod_add, mod_remove, update, AddMod, IDSelector, List, Modloader, VersionLevel, 6 list_list, list_remove, list_version, mod_add, mod_remove, update, AddMod,
7 IDSelector, List, Modloader, VersionLevel,
7}; 8};
8 9
9#[derive(Parser)] 10#[derive(Parser)]
@@ -170,7 +171,11 @@ async fn main() {
170 } => { 171 } => {
171 let listf = match list { 172 let listf = match list {
172 Some(list) => lists_get(&config, &list).unwrap(), 173 Some(list) => lists_get(&config, &list).unwrap(),
173 None => lists_get(&config, &config_get_current_list(&config).unwrap()).unwrap(), 174 None => lists_get(
175 &config,
176 &config_get_current_list(&config).unwrap(),
177 )
178 .unwrap(),
174 }; 179 };
175 180
176 let marked_id = match version { 181 let marked_id = match version {
@@ -188,7 +193,11 @@ async fn main() {
188 ModCommands::Remove { id, list } => { 193 ModCommands::Remove { id, list } => {
189 let listf = match list { 194 let listf = match list {
190 Some(list) => lists_get(&config, &list).unwrap(), 195 Some(list) => lists_get(&config, &list).unwrap(),
191 None => lists_get(&config, &config_get_current_list(&config).unwrap()).unwrap(), 196 None => lists_get(
197 &config,
198 &config_get_current_list(&config).unwrap(),
199 )
200 .unwrap(),
192 }; 201 };
193 mod_remove(&config, &id, &listf) 202 mod_remove(&config, &id, &listf)
194 } 203 }