1use std::path::Path;
4
5pub mod mods;
6pub mod structs;
7
8use inner_future::stream::StreamExt;
9
10use self::structs::VersionInfo;
11use crate::prelude::*;
12
13pub struct Version {
15 pub name: String,
17 pub version_type: VersionType,
19 pub created_date: std::time::SystemTime,
21 pub access_date: std::time::SystemTime,
23}
24
25impl Default for Version {
26 fn default() -> Self {
27 Self {
28 name: String::new(),
29 version_type: VersionType::Unknown,
30 created_date: std::time::SystemTime::UNIX_EPOCH,
31 access_date: std::time::SystemTime::UNIX_EPOCH,
32 }
33 }
34}
35
36pub async fn get_avaliable_versions(
38 version_directory_path: impl AsRef<Path>,
39) -> DynResult<Vec<Version>> {
40 let mut version_info = VersionInfo {
41 version_base: version_directory_path
42 .as_ref()
43 .to_string_lossy()
44 .to_string(),
45 ..Default::default()
46 };
47 if version_directory_path.as_ref().is_dir() {
48 let mut entries = inner_future::fs::read_dir(version_directory_path.as_ref()).await?;
49 let mut result = Vec::with_capacity(32);
50 while let Some(entry) = entries.try_next().await? {
51 let (created_date, access_date) = if let Ok(metadata) = entry.metadata().await {
52 (
53 metadata
54 .created()
55 .unwrap_or(std::time::SystemTime::UNIX_EPOCH),
56 metadata
57 .accessed()
58 .unwrap_or(std::time::SystemTime::UNIX_EPOCH),
59 )
60 } else {
61 (
62 std::time::SystemTime::UNIX_EPOCH,
63 std::time::SystemTime::UNIX_EPOCH,
64 )
65 };
66 if entry.file_type().await?.is_dir() {
67 let entry = entry
68 .path()
69 .file_name()
70 .unwrap()
71 .to_str()
72 .unwrap()
73 .to_string();
74 version_info.version = entry.to_owned();
75 if version_info.load().await.is_ok() {
76 result.push(Version {
77 name: entry,
78 version_type: version_info.guess_version_type(),
79 created_date,
80 access_date,
81 });
82 } else {
83 result.push(Version {
84 name: entry,
85 version_type: VersionType::Unknown,
86 created_date,
87 access_date,
88 });
89 }
90 }
91 }
92 Ok(result)
93 } else {
94 Ok(vec![])
95 }
96}
97
98#[derive(Debug, Clone, Copy, PartialEq, Eq)]
100pub enum VersionType {
101 Vanilla,
103 Forge,
105 Fabric,
107 QuiltMC,
109 Optifine,
113 Unknown,
115}
116
117impl Default for VersionType {
118 fn default() -> Self {
119 Self::Unknown
120 }
121}
122
123#[derive(Debug, Clone, PartialEq, Eq)]
125pub enum LoadVersionInfoError {
126 VersionBaseMissing,
128 MainJarFileMissing,
130 VersionFileMissing,
132 VersionFileOpenFail,
134 SCLConfigFileOpenFail,
136 ParseError(String),
138}