diff options
Diffstat (limited to 'src/lib.rs')
-rw-r--r-- | src/lib.rs | 111 |
1 files changed, 110 insertions, 1 deletions
@@ -6,9 +6,10 @@ pub mod db; | |||
6 | pub mod error; | 6 | pub mod error; |
7 | pub mod files; | 7 | pub mod files; |
8 | 8 | ||
9 | use std::fmt::Display; | 9 | use std::{fmt::Display, fs::{File, remove_file, self}, io::{Write, Read}, time::Duration}; |
10 | 10 | ||
11 | pub use apis::*; | 11 | pub use apis::*; |
12 | use apis::modrinth::{get_game_versions, GameVersion, GameVersionType}; | ||
12 | pub use commands::*; | 13 | pub use commands::*; |
13 | use error::{ErrorType, MLError, MLE}; | 14 | use error::{ErrorType, MLError, MLE}; |
14 | use serde::{Deserialize, Serialize, de::Visitor}; | 15 | use serde::{Deserialize, Serialize, de::Visitor}; |
@@ -77,3 +78,111 @@ impl<'de> Deserialize<'de> for Modloader { | |||
77 | deserializer.deserialize_identifier(FieldVisitor) | 78 | deserializer.deserialize_identifier(FieldVisitor) |
78 | } | 79 | } |
79 | } | 80 | } |
81 | |||
82 | #[derive(Debug, Clone)] | ||
83 | pub enum VersionLevel { | ||
84 | Release, | ||
85 | Snapshot, | ||
86 | Version(String) | ||
87 | } | ||
88 | |||
89 | /// Checks if update needed (time) | ||
90 | /// if yes: get versions, update | ||
91 | pub async fn check_game_versions(path: &str, force: bool) -> MLE<()> { | ||
92 | let creation_time = fs::metadata(path)?.created()?; | ||
93 | if !force && creation_time.elapsed().unwrap() < Duration::from_secs(60 * 60 * 24) { return Ok(()); } | ||
94 | print!("Update minecraft versions"); | ||
95 | std::io::stdout().flush()?; | ||
96 | let versions = get_game_versions().await; | ||
97 | remove_file(path)?; | ||
98 | let mut file = File::create(path)?; | ||
99 | file.write_all(&serde_json::to_string_pretty(&versions)?.as_bytes())?; | ||
100 | println!(" ✓"); | ||
101 | Ok(()) | ||
102 | } | ||
103 | |||
104 | /// Loads game versions | ||
105 | pub fn load_game_versions(path: &str) -> MLE<Vec<GameVersion>> { | ||
106 | let mut file = File::open(path)?; | ||
107 | let mut data = String::new(); | ||
108 | file.read_to_string(&mut data)?; | ||
109 | let versions: Vec<GameVersion> = serde_json::from_str(&data)?; | ||
110 | Ok(versions) | ||
111 | } | ||
112 | |||
113 | impl VersionLevel { | ||
114 | |||
115 | pub fn from(str: &str) -> Self { | ||
116 | match str { | ||
117 | "release" => VersionLevel::Release, | ||
118 | "snapshot" => VersionLevel::Snapshot, | ||
119 | _ => VersionLevel::Version(String::from(str)), | ||
120 | } | ||
121 | } | ||
122 | |||
123 | pub fn get(self, versions_path: &str) -> MLE<String> { | ||
124 | let path = format!("{}/versions.json", versions_path); | ||
125 | let mut versions = load_game_versions(&path)?.into_iter(); | ||
126 | |||
127 | match self { | ||
128 | VersionLevel::Release => { | ||
129 | let release = versions.find(|ver| ver.version_type == GameVersionType::release).unwrap(); | ||
130 | println!("{:?}", release); | ||
131 | Ok(release.version) | ||
132 | }, | ||
133 | VersionLevel::Snapshot => { | ||
134 | let snapshot = versions.find(|ver| ver.version_type == GameVersionType::snapshot).unwrap(); | ||
135 | println!("{:?}", snapshot); | ||
136 | Ok(snapshot.version) | ||
137 | }, | ||
138 | VersionLevel::Version(v) => { | ||
139 | if versions.find(|ver| ver.version == v).is_some() { | ||
140 | Ok(v) | ||
141 | } else { | ||
142 | Err(MLError::new(ErrorType::ConfigError, "unknown minecraft version")) | ||
143 | } | ||
144 | }, | ||
145 | } | ||
146 | } | ||
147 | } | ||
148 | |||
149 | impl Serialize for VersionLevel { | ||
150 | fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | ||
151 | where | ||
152 | S: serde::Serializer { | ||
153 | match self { | ||
154 | VersionLevel::Release => serializer.serialize_str("release"), | ||
155 | VersionLevel::Snapshot => serializer.serialize_str("snapshot"), | ||
156 | VersionLevel::Version(v) => serializer.serialize_str(v), | ||
157 | } | ||
158 | } | ||
159 | } | ||
160 | |||
161 | impl<'de> Deserialize<'de> for VersionLevel { | ||
162 | fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> | ||
163 | where | ||
164 | D: serde::Deserializer<'de>, | ||
165 | { | ||
166 | struct FieldVisitor; | ||
167 | |||
168 | impl<'de> Visitor<'de> for FieldVisitor { | ||
169 | type Value = VersionLevel; | ||
170 | |||
171 | fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
172 | formatter.write_str("`fabric`, `forge` or `quilt`") | ||
173 | } | ||
174 | |||
175 | fn visit_str<E>(self, v: &str) -> Result<VersionLevel, E> | ||
176 | where | ||
177 | E: serde::de::Error, { | ||
178 | match v { | ||
179 | "release" => Ok(VersionLevel::Release), | ||
180 | "snapshot" => Ok(VersionLevel::Snapshot), | ||
181 | _ => Ok(VersionLevel::Version(String::from(v))) | ||
182 | } | ||
183 | } | ||
184 | } | ||
185 | |||
186 | deserializer.deserialize_identifier(FieldVisitor) | ||
187 | } | ||
188 | } | ||