summaryrefslogtreecommitdiffstats
path: root/src/launcher.rs
diff options
context:
space:
mode:
authorLibravatar bigfoot547 <[email protected]>2025-01-12 03:58:01 -0600
committerLibravatar bigfoot547 <[email protected]>2025-01-12 03:58:01 -0600
commitc0986823af246ccee2247b881974a2b7ce6ee491 (patch)
tree9dcb8a66692d5c0067450c60e1de72bd4fce92a5 /src/launcher.rs
parentuse a macro for map_err (diff)
add some logging and stuff
Diffstat (limited to 'src/launcher.rs')
-rw-r--r--src/launcher.rs79
1 files changed, 71 insertions, 8 deletions
diff --git a/src/launcher.rs b/src/launcher.rs
index e207281..a7ef8c9 100644
--- a/src/launcher.rs
+++ b/src/launcher.rs
@@ -11,22 +11,64 @@ use std::error::Error;
use std::fmt::{Display, Formatter};
use std::io::ErrorKind;
use std::path::{Path, PathBuf};
+use const_format::formatcp;
+use futures::TryFutureExt;
+use log::{debug, warn};
use serde::{Deserialize, Serialize};
use sha1_smol::Sha1;
use sysinfo::System;
use tokio::fs::File;
+use tokio::{fs, io};
use tokio::io::AsyncReadExt;
use version::VersionList;
use profile::{Instance, Profile};
use crate::launcher::version::{VersionResolveError, VersionResult};
use crate::version::{Library, OSRestriction, OperatingSystem};
-#[derive(Debug, Clone, Serialize, Deserialize)]
+#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct Settings {
profiles: HashMap<String, Profile>,
instances: HashMap<String, Instance>
}
+#[derive(Debug)]
+enum SettingsLoadError {
+ IO(io::Error),
+ Format(serde_json::Error)
+}
+
+impl Display for SettingsLoadError {
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
+ match self {
+ SettingsLoadError::IO(err) => write!(f, "I/O error loading settings: {}", err),
+ SettingsLoadError::Format(err) => write!(f, "settings format error: {}", err),
+ }
+ }
+}
+
+impl Error for SettingsLoadError {
+ fn source(&self) -> Option<&(dyn Error + 'static)> {
+ match self {
+ SettingsLoadError::IO(err) => Some(err),
+ SettingsLoadError::Format(err) => Some(err),
+ }
+ }
+}
+
+impl Settings {
+ async fn load(path: impl AsRef<Path>) -> Result<Settings, SettingsLoadError> {
+ let data = match fs::read_to_string(&path).await {
+ Ok(data) => data,
+ Err(e) => return match e.kind() {
+ ErrorKind::NotFound => Ok(Settings::default()),
+ _ => Err(SettingsLoadError::IO(e))
+ }
+ };
+
+ serde_json::from_str(data.as_str()).map_err(SettingsLoadError::Format)
+ }
+}
+
struct SystemInfo {
os: OperatingSystem,
os_version: String,
@@ -84,7 +126,19 @@ impl Launcher {
let home = home.to_owned();
let versions_home = home.join("versions");
let versions;
-
+
+ match tokio::fs::create_dir_all(&home).await {
+ Ok(_) => (),
+ Err(e) => match e.kind() {
+ ErrorKind::AlreadyExists => (),
+ _ => {
+ warn!("Failed to create launcher home directory: {}", e);
+ return Err(e.into());
+ }
+ }
+ }
+
+ debug!("Version list online?: {online}");
if online {
versions = VersionList::online(versions_home.as_ref()).await?;
} else {
@@ -92,7 +146,7 @@ impl Launcher {
}
let settings_path = home.join("ozone.json");
- let settings = serde_json::from_str(tokio::fs::read_to_string(&settings_path).await?.as_str())?;
+ let settings = Settings::load(&settings_path).await?;
Ok(Launcher {
online,
@@ -162,7 +216,16 @@ impl Display for LibraryError {
impl Error for LibraryError {}
+const ARCH_BITS: &'static str = formatcp!("{}", usize::BITS);
+
impl LibraryRepository {
+ fn lib_replace(key: &str) -> Option<Cow<'static, str>> {
+ match key {
+ "arch" => Some(Cow::Borrowed(ARCH_BITS)),
+ _ => None
+ }
+ }
+
fn get_artifact_base_dir(name: &str) -> Option<PathBuf> {
let end_of_gid = name.find(':')?;
@@ -174,14 +237,14 @@ impl LibraryRepository {
if let Some(classifier) = classifier {
match n.len() {
- 3 => Some(PathBuf::from(format!("{}-{}-{}.jar", n[1], n[2], classifier))),
- 4 => Some(PathBuf::from(format!("{}-{}-{}-{}.jar", n[1], n[2], classifier, n[3]))),
+ 3 => Some(PathBuf::from(strsub::replace_thru(format!("{}-{}-{}.jar", n[1], n[2], classifier), Self::lib_replace))),
+ 4 => Some(PathBuf::from(strsub::replace_thru(format!("{}-{}-{}-{}.jar", n[1], n[2], classifier, n[3]), Self::lib_replace))),
_ => None
}
} else {
match n.len() {
- 3 => Some(PathBuf::from(format!("{}-{}.jar", n[1], n[2]))),
- 4 => Some(PathBuf::from(format!("{}-{}-{}.jar", n[1], n[2], n[3]))),
+ 3 => Some(PathBuf::from(strsub::replace_thru(format!("{}-{}.jar", n[1], n[2]), Self::lib_replace))),
+ 4 => Some(PathBuf::from(strsub::replace_thru(format!("{}-{}-{}.jar", n[1], n[2], n[3]), Self::lib_replace))),
_ => None
}
}
@@ -238,4 +301,4 @@ impl SystemInfo {
&& restriction.version.as_deref().is_none_or(|pat| pat.is_match(&self.os_version))
&& restriction.arch.as_deref().is_none_or(|pat| pat.is_match(&self.arch))
}
-} \ No newline at end of file
+}