Skip to content

Commit 4d2eab5

Browse files
Refactor condensed multiple bools to Checks struct
1 parent 90f4350 commit 4d2eab5

File tree

5 files changed

+171
-68
lines changed

5 files changed

+171
-68
lines changed

src/add/curseforge.rs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ use crate::{
33
upgrade::mod_downloadable,
44
};
55

6+
use super::Checks;
7+
68
fn project_exist(profile: &Profile, project: &furse::structures::mod_structs::Mod) -> bool {
79
profile.mods.iter().any(|mod_| {
810
mod_.name.to_lowercase() == project.name.to_lowercase()
@@ -40,9 +42,7 @@ pub async fn curseforge(
4042
curseforge: &furse::Furse,
4143
project_id: i32,
4244
profile: &mut Profile,
43-
perform_checks: bool,
44-
check_game_version: bool,
45-
check_mod_loader: bool,
45+
checks: &Checks,
4646
) -> super::Result<String> {
4747
let project = curseforge.get_mod(project_id).await?;
4848

@@ -62,19 +62,18 @@ pub async fn curseforge(
6262
}
6363

6464
// Check if the project is compatible
65-
if perform_checks
66-
&& !is_project_compatible(curseforge, &project, profile, check_game_version).await?
65+
if checks.perform_checks()
66+
&& !is_project_compatible(curseforge, &project, profile, checks.game_version()).await?
6767
{
6868
return Err(super::Error::Incompatible);
6969
}
7070

7171
// Add it to the profile
72-
profile.mods.push(Mod {
73-
name: project.name.trim().to_string(),
74-
identifier: ModIdentifier::CurseForgeProject(project.id),
75-
check_game_version,
76-
check_mod_loader,
77-
});
72+
profile.mods.push(Mod::new(
73+
project.name.trim(),
74+
ModIdentifier::CurseForgeProject(project.id),
75+
checks,
76+
));
7877

7978
Ok(project.name)
8079
}

src/add/github.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use crate::{
55
upgrade::mod_downloadable,
66
};
77

8+
use super::Checks;
9+
810
fn project_exist(profile: &Profile, repo: &Repository, repo_name: &(String, String)) -> bool {
911
profile.mods.iter().any(|mod_| {
1012
mod_.name.to_lowercase() == repo.name.to_lowercase()
@@ -40,8 +42,7 @@ pub async fn github(
4042
repo_handler: &octocrab::repos::RepoHandler<'_>,
4143
profile: &mut Profile,
4244
perform_checks: bool,
43-
check_game_version: bool,
44-
check_mod_loader: bool,
45+
checks: &Checks,
4546
) -> super::Result<String> {
4647
let repo = repo_handler.get().await?;
4748
let repo_name = (
@@ -66,18 +67,17 @@ pub async fn github(
6667
}
6768

6869
// Check if the repo is compatible
69-
if !is_project_compatible(profile, &releases, check_game_version).await? {
70+
if !is_project_compatible(profile, &releases, checks.game_version()).await? {
7071
return Err(super::Error::Incompatible);
7172
}
7273
}
7374

7475
// Add it to the profile
75-
profile.mods.push(Mod {
76-
name: repo.name.trim().to_string(),
77-
identifier: ModIdentifier::GitHubRepository(repo_name),
78-
check_game_version,
79-
check_mod_loader,
80-
});
76+
profile.mods.push(Mod::new(
77+
repo.name.trim(),
78+
ModIdentifier::GitHubRepository(repo_name),
79+
checks,
80+
));
8181

8282
Ok(repo.name)
8383
}

src/add/mod.rs

Lines changed: 127 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::cell::Cell;
2+
13
use crate::config::structs::Profile;
24
use reqwest::StatusCode;
35

@@ -31,6 +33,88 @@ pub enum Error {
3133

3234
pub type Result<T> = std::result::Result<T, Error>;
3335

36+
/// Single sturct to condense check flags for game version, mod loader and to-check
37+
/// Saves space, reduce complexity in fn args and is fast
38+
///
39+
/// Bit mappings (LTR: [7,6,5,4,3,2,1,0]):
40+
/// 0: flag for "perform checks"
41+
/// 1: flag for "game version"
42+
/// 2: flag for "mod loader"
43+
#[derive(Default)]
44+
pub struct Checks(Cell<u8>);
45+
46+
impl Checks {
47+
/// Generates new [Checks] will all values set to [true]
48+
pub fn new_all_set() -> Self {
49+
Self(Cell::new(0b00000111))
50+
}
51+
52+
/// Generates [Checks] from given predicate
53+
pub fn from(checks: bool, game_version: bool, mod_loader: bool) -> Self {
54+
let ret = Self::default();
55+
if checks {
56+
ret.set_perform_check();
57+
}
58+
if game_version {
59+
ret.set_game_version();
60+
}
61+
if mod_loader {
62+
ret.set_mod_loader();
63+
}
64+
ret
65+
}
66+
67+
/// Set "perform_checks" bit to true
68+
pub fn set_perform_check(&self) {
69+
self.0.set(self.0.get() | 1 << 0);
70+
}
71+
72+
/// Set "game_version" bit to true
73+
pub fn set_game_version(&self) {
74+
self.0.set(self.0.get() | 1 << 1);
75+
}
76+
77+
/// Set "mod_loader" bit to true
78+
pub fn set_mod_loader(&self) {
79+
self.0.set(self.0.get() | 1 << 2);
80+
}
81+
82+
/// Set "perform_checks" bit to false
83+
pub fn unset_perform_check(&self) {
84+
self.0.set(self.0.get() & 1 << 0);
85+
}
86+
87+
/// Set "game_version" bit to false
88+
pub fn unset_game_version(&self) {
89+
self.0.set(self.0.get() & 1 << 1);
90+
}
91+
92+
/// Set "mod_loader" bit to true
93+
pub fn unset_mod_loader(&self) {
94+
self.0.set(self.0.get() & 1 << 2);
95+
}
96+
97+
/// Return "perform_checks" bit status
98+
pub fn perform_checks(&self) -> bool {
99+
self.0.get() & 1 != 0
100+
}
101+
102+
/// Return "game_version" bit status
103+
pub fn game_version(&self) -> bool {
104+
self.0.get() & (1 << 1) != 0
105+
}
106+
107+
/// Return "mod_loader" bit status
108+
pub fn mod_loader(&self) -> bool {
109+
self.0.get() & (1 << 2) != 0
110+
}
111+
112+
/// Reset all bits to 0 (all flags to false)
113+
pub fn reset(&self) {
114+
self.0.set(0);
115+
}
116+
}
117+
34118
impl From<furse::Error> for Error {
35119
fn from(err: furse::Error) -> Self {
36120
if let furse::Error::ReqwestError(source) = &err {
@@ -87,9 +171,7 @@ pub async fn add_multiple(
87171
github,
88172
profile,
89173
&identifier,
90-
true,
91-
true,
92-
true,
174+
&Checks::new_all_set(),
93175
)
94176
.await
95177
{
@@ -107,47 +189,63 @@ pub async fn add_multiple(
107189
(success_names, failures)
108190
}
109191

110-
#[allow(clippy::too_many_arguments)]
111192
pub async fn add_single(
112193
modrinth: &ferinth::Ferinth,
113194
curseforge: &furse::Furse,
114195
github: &octocrab::Octocrab,
115196
profile: &mut Profile,
116197
identifier: &str,
117-
perform_checks: bool,
118-
check_game_version: bool,
119-
check_mod_loader: bool,
198+
checks: &Checks,
120199
) -> Result<String> {
121200
if let Ok(project_id) = identifier.parse() {
122-
curseforge::curseforge(
123-
curseforge,
124-
project_id,
125-
profile,
126-
perform_checks,
127-
check_game_version,
128-
check_mod_loader,
129-
)
130-
.await
201+
curseforge::curseforge(curseforge, project_id, profile, checks).await
131202
} else if identifier.matches('/').count() == 1 {
132203
let split = identifier.split('/').collect::<Vec<_>>();
133204
github::github(
134205
&github.repos(split[0], split[1]),
135206
profile,
136-
perform_checks,
137-
check_game_version,
138-
check_mod_loader,
207+
checks.perform_checks(),
208+
checks,
139209
)
140210
.await
141211
} else {
142-
modrinth::modrinth(
143-
modrinth,
144-
identifier,
145-
profile,
146-
perform_checks,
147-
check_game_version,
148-
check_mod_loader,
149-
)
150-
.await
151-
.map(|o| o.0)
212+
modrinth::modrinth(modrinth, identifier, profile, checks)
213+
.await
214+
.map(|o| o.0)
215+
}
216+
}
217+
218+
#[cfg(test)]
219+
mod test {
220+
use super::Checks;
221+
222+
#[test]
223+
fn check_bit_set_unset() {
224+
let check = Checks::default();
225+
226+
// seting bits
227+
check.set_perform_check();
228+
check.set_mod_loader();
229+
check.set_game_version();
230+
231+
assert!(check.perform_checks() && check.game_version() && check.mod_loader());
232+
233+
// Unset after set
234+
check.unset_perform_check();
235+
check.unset_mod_loader();
236+
check.unset_game_version();
237+
238+
assert!(!(check.perform_checks() && check.game_version() && check.mod_loader()));
239+
240+
// Unset after Unset
241+
check.unset_mod_loader();
242+
243+
assert!(!check.mod_loader());
244+
245+
// set after set
246+
check.set_game_version();
247+
check.set_game_version();
248+
249+
assert!(check.game_version());
152250
}
153251
}

src/add/modrinth.rs

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use crate::{
55
upgrade::check::{game_version_check, mod_loader_check},
66
};
77

8+
use super::Checks;
9+
810
fn project_exist(profile: &Profile, project: &Project) -> bool {
911
profile.mods.iter().any(|mod_| {
1012
mod_.name.to_lowercase() == project.title.to_lowercase()
@@ -26,16 +28,11 @@ fn check_mod_loader_fabric_backwards_compatible(
2628
&& mod_loader_check(Some(ModLoader::Fabric), &project.loaders))
2729
}
2830

29-
fn project_comatible(
30-
profile: &Profile,
31-
project: &Project,
32-
check_game_version: bool,
33-
check_mod_loader: bool,
34-
) -> bool {
31+
fn project_comatible(profile: &Profile, project: &Project, checks: &Checks) -> bool {
3532
game_version_check(
36-
profile.get_version(check_game_version),
33+
profile.get_version(checks.game_version()),
3734
&project.game_versions,
38-
) && check_mod_loader_fabric_backwards_compatible(profile, project, check_mod_loader)
35+
) && check_mod_loader_fabric_backwards_compatible(profile, project, checks.mod_loader())
3936
}
4037

4138
/// Check if the project of `project_id` exists, is a mod, and is compatible with `profile`.
@@ -46,9 +43,7 @@ pub async fn modrinth(
4643
modrinth: &ferinth::Ferinth,
4744
project_id: &str,
4845
profile: &mut Profile,
49-
perform_checks: bool,
50-
check_game_version: bool,
51-
check_mod_loader: bool,
46+
checks: &Checks,
5247
) -> super::Result<(String, Vec<DonationLink>)> {
5348
let project = modrinth.get_project(project_id).await?;
5449

@@ -60,17 +55,15 @@ pub async fn modrinth(
6055
return Err(super::Error::NotAMod);
6156
}
6257

63-
if perform_checks && !project_comatible(profile, &project, check_game_version, check_mod_loader)
64-
{
58+
if checks.perform_checks() && !project_comatible(profile, &project, checks) {
6559
return Err(super::Error::Incompatible);
6660
}
6761

68-
profile.mods.push(Mod {
69-
name: project.title.trim().to_string(),
70-
identifier: ModIdentifier::ModrinthProject(project.id),
71-
check_game_version,
72-
check_mod_loader,
73-
});
62+
profile.mods.push(Mod::new(
63+
project.title.trim(),
64+
ModIdentifier::ModrinthProject(project.id),
65+
checks,
66+
));
7467

7568
Ok((project.title, project.donation_urls))
7669
}

src/config/structs.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use serde::{Deserialize, Serialize};
22
use std::{path::PathBuf, str::FromStr};
33

4+
use crate::add::Checks;
5+
46
#[derive(Deserialize, Serialize, Debug, Default, Clone)]
57
pub struct Config {
68
/// The index of the active profile
@@ -90,6 +92,17 @@ pub struct Mod {
9092
pub check_mod_loader: bool,
9193
}
9294

95+
impl Mod {
96+
pub fn new(name: &str, identifier: ModIdentifier, checks: &Checks) -> Self {
97+
Self {
98+
name: name.into(),
99+
identifier,
100+
check_game_version: checks.game_version(),
101+
check_mod_loader: checks.mod_loader(),
102+
}
103+
}
104+
}
105+
93106
fn is_true(b: &bool) -> bool {
94107
*b
95108
}

0 commit comments

Comments
 (0)