diff options
Diffstat (limited to 'src/data')
-rw-r--r-- | src/data/gameversion.rs | 118 | ||||
-rw-r--r-- | src/data/list.rs | 19 | ||||
-rw-r--r-- | src/data/modification.rs | 11 | ||||
-rw-r--r-- | src/data/modloader.rs | 39 | ||||
-rw-r--r-- | src/data/project.rs | 12 |
5 files changed, 199 insertions, 0 deletions
diff --git a/src/data/gameversion.rs b/src/data/gameversion.rs new file mode 100644 index 0000000..3868502 --- /dev/null +++ b/src/data/gameversion.rs | |||
@@ -0,0 +1,118 @@ | |||
1 | use std::{ | ||
2 | fs::{self, remove_file, File}, | ||
3 | io::{Read, Write}, | ||
4 | time::Duration, | ||
5 | }; | ||
6 | |||
7 | use apis::modrinth::{get_game_versions, GameVersion, GameVersionType}; | ||
8 | use error::{EType, MLErr, MLE}; | ||
9 | use indicatif::{ProgressBar, ProgressStyle}; | ||
10 | use serde::{Deserialize, Serialize}; | ||
11 | |||
12 | use crate::{apis, error, STYLE_MESSAGE}; | ||
13 | |||
14 | #[derive(Debug, Clone, Deserialize, Serialize)] | ||
15 | pub enum VersionLevel { | ||
16 | #[serde(rename(serialize = "release", deserialize = "release"))] | ||
17 | Release, | ||
18 | #[serde(rename(serialize = "snapshot", deserialize = "snapshot"))] | ||
19 | Snapshot, | ||
20 | Version(String), | ||
21 | } | ||
22 | |||
23 | /// Checks if update needed (time) | ||
24 | /// if yes: get versions, update | ||
25 | /// # Errors | ||
26 | pub async fn check_game_versions(path: &str, force: bool) -> MLE<()> { | ||
27 | let p = ProgressBar::new(1); | ||
28 | p.set_style(ProgressStyle::with_template(STYLE_MESSAGE).map_err(|_| { | ||
29 | MLErr::new(EType::LibIndicatif, "template error") | ||
30 | })?); | ||
31 | p.set_message("Update minecraft versions"); | ||
32 | |||
33 | let creation_time = fs::metadata(path)?.created()?; | ||
34 | if !force | ||
35 | && creation_time.elapsed().map_err(|_| MLErr::new(EType::LibIndicatif, "SystemTimeError"))? < Duration::from_secs(60 * 60 * 24) | ||
36 | { | ||
37 | return Ok(()); | ||
38 | } | ||
39 | |||
40 | let versions = get_game_versions().await?; | ||
41 | remove_file(path)?; | ||
42 | let mut file = File::create(path)?; | ||
43 | file.write_all(serde_json::to_string_pretty(&versions)?.as_bytes())?; | ||
44 | |||
45 | p.finish_with_message("Updated minecraft versions"); | ||
46 | Ok(()) | ||
47 | } | ||
48 | |||
49 | /// Loads game versions from file | ||
50 | /// # Errors | ||
51 | pub fn load_game_versions(path: &str) -> MLE<Vec<GameVersion>> { | ||
52 | let mut file = File::open(path)?; | ||
53 | let mut data = String::new(); | ||
54 | file.read_to_string(&mut data)?; | ||
55 | let versions: Vec<GameVersion> = serde_json::from_str(&data)?; | ||
56 | Ok(versions) | ||
57 | } | ||
58 | |||
59 | impl VersionLevel { | ||
60 | pub fn from(str: &str) -> Self { | ||
61 | match str { | ||
62 | "release" => VersionLevel::Release, | ||
63 | "snapshot" => VersionLevel::Snapshot, | ||
64 | _ => VersionLevel::Version(String::from(str)), | ||
65 | } | ||
66 | } | ||
67 | |||
68 | /// . | ||
69 | /// | ||
70 | /// Panics if . | ||
71 | /// # Errors | ||
72 | pub async fn get( | ||
73 | self, | ||
74 | versions_path: &str, | ||
75 | force_update: bool, | ||
76 | ) -> MLE<String> { | ||
77 | let path = format!("{versions_path}/versions.json"); | ||
78 | check_game_versions(&path, force_update).await?; | ||
79 | let mut versions = load_game_versions(&path)?.into_iter(); | ||
80 | |||
81 | match self { | ||
82 | VersionLevel::Release => { | ||
83 | if let Some(release) = versions | ||
84 | .find(|ver| ver.version_type == GameVersionType::release) | ||
85 | { | ||
86 | Ok(release.version) | ||
87 | } else { | ||
88 | Err(MLErr::new( | ||
89 | EType::Other, | ||
90 | "no minecraft release version found", | ||
91 | )) | ||
92 | } | ||
93 | } | ||
94 | VersionLevel::Snapshot => { | ||
95 | if let Some(snapshot) = versions | ||
96 | .find(|ver| ver.version_type == GameVersionType::snapshot) | ||
97 | { | ||
98 | Ok(snapshot.version) | ||
99 | } else { | ||
100 | Err(MLErr::new( | ||
101 | EType::Other, | ||
102 | "no minecraft snapshot version found", | ||
103 | )) | ||
104 | } | ||
105 | } | ||
106 | VersionLevel::Version(v) => { | ||
107 | if versions.any(|ver| ver.version == v) { | ||
108 | Ok(v) | ||
109 | } else { | ||
110 | Err(MLErr::new( | ||
111 | EType::ConfigError, | ||
112 | "unknown minecraft version", | ||
113 | )) | ||
114 | } | ||
115 | } | ||
116 | } | ||
117 | } | ||
118 | } | ||
diff --git a/src/data/list.rs b/src/data/list.rs new file mode 100644 index 0000000..0045b7a --- /dev/null +++ b/src/data/list.rs | |||
@@ -0,0 +1,19 @@ | |||
1 | use crate::{config::Cfg, db::{config_get_current_list, lists_get}, error::MLE}; | ||
2 | |||
3 | use super::modloader::Modloader; | ||
4 | |||
5 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
6 | pub struct List { | ||
7 | pub id: String, | ||
8 | pub mc_version: String, | ||
9 | pub modloader: Modloader, | ||
10 | pub download_folder: String, | ||
11 | } | ||
12 | |||
13 | impl List { | ||
14 | /// # Errors | ||
15 | pub fn get_current_list(config: &Cfg) -> MLE<List> { | ||
16 | let id = config_get_current_list(config)?; | ||
17 | lists_get(config, &id) | ||
18 | } | ||
19 | } | ||
diff --git a/src/data/modification.rs b/src/data/modification.rs new file mode 100644 index 0000000..84047ff --- /dev/null +++ b/src/data/modification.rs | |||
@@ -0,0 +1,11 @@ | |||
1 | #[derive(Debug)] | ||
2 | pub struct AddMod { | ||
3 | pub id: IDSelector, | ||
4 | pub set_version: bool, | ||
5 | } | ||
6 | |||
7 | #[derive(Debug, PartialEq, Eq)] | ||
8 | pub enum IDSelector { | ||
9 | ModificationID(String), | ||
10 | VersionID(String), | ||
11 | } | ||
diff --git a/src/data/modloader.rs b/src/data/modloader.rs new file mode 100644 index 0000000..050213f --- /dev/null +++ b/src/data/modloader.rs | |||
@@ -0,0 +1,39 @@ | |||
1 | use std::fmt::Display; | ||
2 | |||
3 | use serde::{Deserialize, Serialize}; | ||
4 | |||
5 | use crate::error::{EType, MLErr, MLE}; | ||
6 | |||
7 | #[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)] | ||
8 | pub enum Modloader { | ||
9 | #[serde(rename(serialize = "fabric", deserialize = "fabric"))] | ||
10 | Fabric, | ||
11 | #[serde(rename(serialize = "forge", deserialize = "forge"))] | ||
12 | Forge, | ||
13 | #[serde(rename(serialize = "quilt", deserialize = "quilt"))] | ||
14 | Quilt, | ||
15 | } | ||
16 | |||
17 | impl Modloader { | ||
18 | /// # Errors | ||
19 | pub fn from(string: &str) -> MLE<Modloader> { | ||
20 | match string { | ||
21 | "forge" => Ok(Modloader::Forge), | ||
22 | "fabric" => Ok(Modloader::Fabric), | ||
23 | "quilt" => Ok(Modloader::Quilt), | ||
24 | _ => { | ||
25 | Err(MLErr::new(EType::ArgumentError, "UNKNOWN_MODLOADER")) | ||
26 | } | ||
27 | } | ||
28 | } | ||
29 | } | ||
30 | |||
31 | impl 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 | Modloader::Quilt => write!(f, "quilt"), | ||
37 | } | ||
38 | } | ||
39 | } | ||
diff --git a/src/data/project.rs b/src/data/project.rs new file mode 100644 index 0000000..9807867 --- /dev/null +++ b/src/data/project.rs | |||
@@ -0,0 +1,12 @@ | |||
1 | use crate::apis::modrinth::Version; | ||
2 | |||
3 | #[derive(Debug, Clone)] | ||
4 | pub struct ProjectInfo { | ||
5 | pub mod_id: String, | ||
6 | pub slug: String, | ||
7 | pub title: String, | ||
8 | pub current_version: Option<Version>, | ||
9 | pub applicable_versions: Vec<String>, | ||
10 | pub download_link: String, | ||
11 | pub set_version: bool, | ||
12 | } | ||