aboutsummaryrefslogtreecommitdiffstats
path: root/src/platform
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/platform/paths.rs270
1 files changed, 247 insertions, 23 deletions
diff --git a/src/platform/paths.rs b/src/platform/paths.rs
index b430f09..07313fd 100644
--- a/src/platform/paths.rs
+++ b/src/platform/paths.rs
@@ -1,44 +1,268 @@
1use std::{fs::create_dir_all, path::PathBuf}; 1use std::{fs::create_dir_all, path::PathBuf};
2 2
3use crate::{config::Config, errors::McError}; 3use crate::{config::Config, constants::directory, errors::McError};
4 4
5/// ~/.local/share/dml/minecraft 5/// Returns the path to the root Minecraft directory inside the launcher data folder.
6pub fn minecraft_root(cfg: &Config) -> PathBuf { 6///
7/// This directory acts as the root for all Minecraft-related files within the launcher data.
8/// By default, it joins the `minecraft` directory under the data folder (defined by the launcher).
9///
10/// The returned path does not include any specific assets, versions, or libraries directories.
11/// You can use this as the base path to construct other Minecraft-related paths.
12///
13/// # Parameters
14/// - `cfg`: The configuration object (`Config`) containing launcher and Minecraft data folder paths.
15///
16/// # Returns
17/// - A `PathBuf` pointing to the root Minecraft directory.
18pub fn root_directory(cfg: &Config) -> PathBuf {
19 // Remove DEFAULT_LAUNCHER_DIR to avoid duplicate "dml/dml"
7 cfg.data_dir.join("minecraft") 20 cfg.data_dir.join("minecraft")
8} 21}
9 22
10pub fn assets_dir(cfg: &Config) -> PathBuf { 23/// Returns the path to the Minecraft assets directory.
11 minecraft_root(cfg).join("assets") 24///
25/// This is where Minecraft assets such as textures, sounds, and other resources are stored.
26/// The assets directory is located inside the root Minecraft directory and can be used
27/// for accessing game assets.
28///
29/// # Parameters
30/// - `cfg`: The configuration object (`Config`) that contains paths for the launcher and Minecraft data.
31///
32/// # Returns
33/// - A `PathBuf` pointing to the assets directory inside the root Minecraft directory.
34pub fn assets_directory(cfg: &Config) -> PathBuf {
35 root_directory(cfg).join(directory::ASSETS)
12} 36}
13 37
14pub fn game_dir(cfg: &Config) -> PathBuf { minecraft_root(cfg) } 38/// Returns the path to the game directory (same as root directory for now).
15pub fn ensure_dirs(cfg: &Config) -> Result<(), McError> { 39///
16 let root = minecraft_root(cfg); 40/// The game directory currently points to the same location as the root directory.
17 create_dir_all(&root)?; 41/// In future iterations, this could be adjusted if game-specific files need to be handled separately.
18 create_dir_all(root.join("versions"))?; 42///
19 create_dir_all(root.join("libraries"))?; 43/// # Parameters
20 create_dir_all(assets_dir(cfg))?; 44/// - `cfg`: The configuration object (`Config`) that holds the paths to the launcher and Minecraft data.
21 create_dir_all(assets_dir(cfg).join("indexes"))?; 45///
22 create_dir_all(assets_dir(cfg).join("objects"))?; 46/// # Returns
23 create_dir_all(root.join("saves"))?; 47/// - A `PathBuf` pointing to the game directory, which is the same as the root Minecraft directory for now.
48pub fn game_directory(cfg: &Config) -> PathBuf {
49 root_directory(cfg)
50}
51
52/// Ensures that all necessary directories for Minecraft are created.
53///
54/// This function checks if essential directories for Minecraft's file structure exist and creates them
55/// if they do not. This includes directories for versions, libraries, assets, and saves.
56///
57/// # Parameters
58/// - `cfg`: The configuration object (`Config`) that contains paths for the Minecraft data and the required directories.
59///
60/// # Returns
61/// - `Ok(())` if all directories are created successfully.
62/// - `Err(McError)` if an error occurs while creating any directory (such as permission issues).
63///
64/// # Example
65/// ```rust
66/// let cfg = Config { /* configuration values */ };
67/// ensure_directories(&cfg)?;
68/// ```
69///
70/// # Notes
71/// The function creates several directories under the root Minecraft directory, including:
72/// - Root directory
73/// - Versions
74/// - Libraries
75/// - Assets (with subdirectories for `indexes` and `objects`)
76/// - Saves
77/// Each of these directories is essential for managing Minecraft game data and resources.
78pub fn ensure_directories(cfg: &Config) -> Result<(), McError> {
79 let root: PathBuf = root_directory(cfg);
80
81 for dir in [
82 root.clone(),
83 root.join(directory::VERSIONS),
84 root.join(directory::LIBRARIES),
85 assets_directory(cfg),
86 assets_directory(cfg).join(directory::INDEXES),
87 assets_directory(cfg).join(directory::OBJECTS),
88 root.join(directory::SAVES),
89 ] {
90 create_dir_all(dir)?;
91 }
24 92
25 Ok(()) 93 Ok(())
26} 94}
27 95
96/// Returns the path to a specific version directory inside the root Minecraft directory.
97///
98/// This directory is where the game version-specific files (such as the `.jar` file) are stored.
99/// The path is constructed by joining the `versions` directory with the provided version name.
100///
101/// # Parameters
102/// - `cfg`: The configuration object (`Config`) containing paths for the Minecraft data.
103/// - `version`: The version of Minecraft (e.g., "1.18.2") to generate the path for.
104///
105/// # Returns
106/// - A `PathBuf` pointing to the directory for the specified version inside the root Minecraft directory.
28pub fn version_dir(cfg: &Config, version: &str) -> PathBuf { 107pub fn version_dir(cfg: &Config, version: &str) -> PathBuf {
29 minecraft_root(cfg).join("versions").join(version) 108 root_directory(cfg)
109 .join(directory::VERSIONS)
110 .join(version)
30} 111}
31 112
32pub fn client_jar(cfg: &Config, version: &str) -> Result<PathBuf, McError> { 113/// Returns the path to the client `.jar` file for a specific Minecraft version.
33 Ok(version_dir(cfg, version).join(format!("{version}.jar"))) 114///
115/// This file is typically used to run the Minecraft client for a particular version.
116/// The path is constructed by joining the version directory with the name of the `.jar` file.
117///
118/// # Parameters
119/// - `cfg`: The configuration object (`Config`) containing paths for the Minecraft data.
120/// - `version`: The version of Minecraft (e.g., "1.18.2") to generate the path for.
121///
122/// # Returns
123/// - A `PathBuf` pointing to the `.jar` file for the specified version in the version directory.
124pub fn client_jar(cfg: &Config, version: &str) -> PathBuf {
125 version_dir(cfg, version).join(format!("{version}.jar"))
34} 126}
35 127
36pub fn library_file(cfg: &Config, rel_path: &str) -> Result<PathBuf, McError> { 128/// Returns the path to a specific library file inside the library directory.
37 Ok(minecraft_root(cfg) 129///
38 .join("libraries") 130/// This function is used to access library files required for running Minecraft. The `rel_path`
39 .join(rel_path)) 131/// argument specifies the relative path inside the `libraries` directory. It is useful for handling
132/// dependencies or loading required libraries based on the game version.
133///
134/// # Parameters
135/// - `cfg`: The configuration object (`Config`) that contains paths for the Minecraft data.
136/// - `rel_path`: The relative path of the library file inside the `libraries` directory.
137///
138/// # Returns
139/// - A `PathBuf` pointing to the specified library file inside the `libraries` directory.
140pub fn library_file(cfg: &Config, rel_path: &str) -> PathBuf {
141 root_directory(cfg)
142 .join(directory::LIBRARIES)
143 .join(rel_path)
40} 144}
41 145
146/// Returns the path to the natives directory for a specific Minecraft version.
147///
148/// The natives directory contains platform-specific native libraries (e.g., `.dll`, `.so`, `.dylib`)
149/// that Minecraft uses to run the game. This function returns the path to the directory for the
150/// specified version.
151///
152/// # Parameters
153/// - `cfg`: The configuration object (`Config`) containing paths for the Minecraft data.
154/// - `version`: The version of Minecraft (e.g., "1.18.2") to generate the path for.
155///
156/// # Returns
157/// - A `PathBuf` pointing to the natives directory for the specified version.
42pub fn natives_dir(cfg: &Config, version: &str) -> PathBuf { 158pub fn natives_dir(cfg: &Config, version: &str) -> PathBuf {
43 version_dir(cfg, version).join("natives") 159 version_dir(cfg, version).join(directory::NATIVES)
160}
161
162// /// Path to a version’s saves directory.
163// pub fn saves_dir(cfg: &Config) -> PathBuf {
164// minecraft_root(cfg).join(dirs::SAVES)
165// }
166
167#[cfg(test)]
168mod tests {
169 use super::*;
170 use std::path::Path;
171
172 fn test_config(tmp: &Path) -> Config {
173 Config {
174 data_dir: tmp.to_path_buf(),
175 ..Default::default()
176 }
177 }
178
179 #[test]
180 fn root_directory_is_correct() {
181 let tmp = tempfile::tempdir().unwrap();
182 let cfg = test_config(tmp.path());
183
184 let root = root_directory(&cfg);
185 assert_eq!(root, tmp.path().join("minecraft"));
186 }
187
188 #[test]
189 fn assets_directory_is_correct() {
190 let tmp = tempfile::tempdir().unwrap();
191 let cfg = test_config(tmp.path());
192
193 let assets = assets_directory(&cfg);
194 assert_eq!(assets, root_directory(&cfg).join(directory::ASSETS));
195 }
196
197 #[test]
198 fn version_paths_are_correct() {
199 let tmp = tempfile::tempdir().unwrap();
200 let cfg = test_config(tmp.path());
201
202 let version = "1.20.1";
203 assert_eq!(
204 version_dir(&cfg, version),
205 root_directory(&cfg)
206 .join(directory::VERSIONS)
207 .join(version)
208 );
209
210 assert_eq!(
211 client_jar(&cfg, version),
212 version_dir(&cfg, version).join("1.20.1.jar")
213 );
214 }
215
216 #[test]
217 fn library_file_path_is_correct() {
218 let tmp = tempfile::tempdir().unwrap();
219 let cfg = test_config(tmp.path());
220
221 let rel = "com/example/lib.jar";
222 assert_eq!(
223 library_file(&cfg, rel),
224 root_directory(&cfg)
225 .join(directory::LIBRARIES)
226 .join(rel)
227 );
228 }
229
230 #[test]
231 fn natives_dir_path_is_correct() {
232 let tmp = tempfile::tempdir().unwrap();
233 let cfg = test_config(tmp.path());
234
235 let version = "1.20.1";
236 assert_eq!(
237 natives_dir(&cfg, version),
238 version_dir(&cfg, version).join(directory::NATIVES)
239 );
240 }
241
242 #[test]
243 fn ensure_directories_creates_structure() {
244 let tmp = tempfile::tempdir().unwrap();
245 let cfg = test_config(tmp.path());
246
247 ensure_directories(&cfg).unwrap();
248
249 let root = root_directory(&cfg);
250
251 let expected_dirs = [
252 root.clone(),
253 root.join(directory::VERSIONS),
254 root.join(directory::LIBRARIES),
255 root.join(directory::ASSETS),
256 root.join(directory::ASSETS)
257 .join(directory::INDEXES),
258 root.join(directory::ASSETS)
259 .join(directory::OBJECTS),
260 root.join(directory::SAVES),
261 ];
262
263 for dir in expected_dirs {
264 assert!(dir.exists(), "Missing directory: {:?}", dir);
265 assert!(dir.is_dir());
266 }
267 }
44} 268}