summaryrefslogtreecommitdiff
path: root/src/data/gameversion.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/data/gameversion.rs')
-rw-r--r--src/data/gameversion.rs118
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 @@
1use std::{
2 fs::{self, remove_file, File},
3 io::{Read, Write},
4 time::Duration,
5};
6
7use apis::modrinth::{get_game_versions, GameVersion, GameVersionType};
8use error::{EType, MLErr, MLE};
9use indicatif::{ProgressBar, ProgressStyle};
10use serde::{Deserialize, Serialize};
11
12use crate::{apis, error, STYLE_MESSAGE};
13
14#[derive(Debug, Clone, Deserialize, Serialize)]
15pub 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
26pub 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
51pub 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
59impl 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}