diff options
Diffstat (limited to 'src/data/gameversion.rs')
-rw-r--r-- | src/data/gameversion.rs | 118 |
1 files changed, 118 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 | } | ||