diff options
| author | 2025-01-22 02:08:31 -0600 | |
|---|---|---|
| committer | 2025-01-22 02:10:20 -0600 | |
| commit | e88c17a44c94f788e945c5728bc18beca7e0f8a6 (patch) | |
| tree | 586873a545cb6bc799129219d5e809106daa58c1 /src/launcher | |
| parent | support jre specified in profile (diff) | |
get started on downloading JREs
also refactor ensure file logic
Diffstat (limited to 'src/launcher')
| -rw-r--r-- | src/launcher/jre.rs | 101 | ||||
| -rw-r--r-- | src/launcher/jre/arch.rs | 45 | ||||
| -rw-r--r-- | src/launcher/jre/manifest.rs | 49 |
3 files changed, 195 insertions, 0 deletions
diff --git a/src/launcher/jre.rs b/src/launcher/jre.rs new file mode 100644 index 0000000..2979c52 --- /dev/null +++ b/src/launcher/jre.rs @@ -0,0 +1,101 @@ +use std::error::Error; +use std::fmt::{Display, Formatter}; +use std::path::{Path, PathBuf}; +use log::{debug, info, warn}; +use tokio::{fs, io}; + +mod arch; +mod manifest; + +use arch::JRE_ARCH; +use manifest::JavaRuntimesManifest; +use crate::launcher::jre::manifest::JavaRuntimeManifest; +use super::constants; + +pub struct JavaRuntimeRepository { + home: PathBuf, + manifest: JavaRuntimesManifest +} + +impl JavaRuntimeRepository { + pub async fn new(home: impl AsRef<Path>) -> Result<Self, JavaRuntimeError> { + info!("Java runtime architecture is \"{}\".", JRE_ARCH); + + fs::create_dir_all(&home).await.map_err(|e| JavaRuntimeError::IO { what: "creating home directory", error: e })?; + + let manifest: JavaRuntimesManifest = reqwest::get(constants::URL_JRE_MANIFEST).await + .map_err(|e| JavaRuntimeError::Download { + what: "runtime manifest (all.json)", + error: e + })?.json().await + .map_err(|e| JavaRuntimeError::Download { + what: "runtime manifest (all.json)", + error: e + })?; + + Ok(JavaRuntimeRepository { + home: home.as_ref().to_path_buf(), + manifest + }) + } + + pub async fn choose_runtime(&self, component: &str) -> Result<JavaRuntimeManifest, JavaRuntimeError> { + let Some(runtime_components) = self.manifest.get(JRE_ARCH) else { + return Err(JavaRuntimeError::UnsupportedArch(JRE_ARCH)); + }; + + let Some(runtime_component) = runtime_components.get(component) else { + return Err(JavaRuntimeError::UnsupportedComponent { arch: JRE_ARCH, component: component.to_owned() }); + }; + + let Some(runtime) = runtime_component.iter().filter(|r| r.availability.progress == 100).next() else { + if !runtime_components.is_empty() { + warn!("Weird: the only java runtimes in {JRE_ARCH}.{component} has a progress of less than 100!"); + } + + return Err(JavaRuntimeError::UnsupportedComponent { arch: JRE_ARCH, component: component.to_owned() }); + }; + + let Some(ref url) = runtime.manifest.url else { + return Err(JavaRuntimeError::MalformedManifest); + }; + + debug!("Ensuring manifest for runtime {JRE_ARCH}.{component}: {url}"); + + + // hmm maybe + + todo!() + } +} + +#[derive(Debug)] +pub enum JavaRuntimeError { + IO { what: &'static str, error: io::Error }, + Download { what: &'static str, error: reqwest::Error }, + UnsupportedArch(&'static str), + UnsupportedComponent { arch: &'static str, component: String }, + MalformedManifest +} + +impl Display for JavaRuntimeError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + JavaRuntimeError::IO { what, error } => write!(f, "i/o error ({}): {}", what, error), + JavaRuntimeError::Download { what, error } => write!(f, "error downloading {}: {}", what, error), + JavaRuntimeError::UnsupportedArch(arch) => write!(f, r#"unsupported architecture "{arch}""#), + JavaRuntimeError::UnsupportedComponent { arch, component } => write!(f, r#"unsupported component "{component}" for architecture "{arch}""#), + JavaRuntimeError::MalformedManifest => f.write_str("malformed runtime manifest (launcher bug?)"), + } + } +} + +impl Error for JavaRuntimeError { + fn source(&self) -> Option<&(dyn Error + 'static)> { + match self { + JavaRuntimeError::IO { error, .. } => Some(error), + JavaRuntimeError::Download { error, .. } => Some(error), + _ => None + } + } +} diff --git a/src/launcher/jre/arch.rs b/src/launcher/jre/arch.rs new file mode 100644 index 0000000..e984171 --- /dev/null +++ b/src/launcher/jre/arch.rs @@ -0,0 +1,45 @@ +use cfg_if::cfg_if; + +macro_rules! define_arch { + ($arch:expr) => { + pub const JRE_ARCH: &str = $arch; + } +} + +cfg_if! { + if #[cfg(target_os = "windows")] { + cfg_if! { + if #[cfg(target_arch = "x86_64")] { + define_arch!("windows-x64"); + } else if #[cfg(target_arch = "x86")] { + define_arch!("windows-x86"); + } else if #[cfg(target_arch = "aarch64")] { + define_arch!("windows-arm64"); + } else { + define_arch!("gamecore"); + } + } + } else if #[cfg(target_os = "linux")] { + cfg_if! { + if #[cfg(target_arch = "x86_64")] { + define_arch!("linux"); + } else if #[cfg(target_arch = "x86")] { + define_arch!("linux-i386"); + } else { + define_arch!("gamecore"); + } + } + } else if #[cfg(target_os = "macos")] { + cfg_if! { + if #[cfg(target_arch = "aarch64")] { + define_arch!("mac-os-arm64"); + } else if #[cfg(target_arch = "x86_64")] { + define_arch!("mac-os"); + } else { + define_arch!("gamecore"); + } + } + } else { + define_arch!("gamecore"); + } +} diff --git a/src/launcher/jre/manifest.rs b/src/launcher/jre/manifest.rs new file mode 100644 index 0000000..9b84377 --- /dev/null +++ b/src/launcher/jre/manifest.rs @@ -0,0 +1,49 @@ +use std::collections::HashMap; +use serde::Deserialize; +use crate::version::DownloadInfo; + +#[derive(Debug, Deserialize)] +pub struct Availability { + pub group: u32, // unknown meaning + pub progress: u32 // unknown meaning +} + +#[derive(Debug, Deserialize)] +pub struct Version { + pub name: String, + pub version: String +} + +#[derive(Debug, Deserialize)] +pub struct JavaRuntimeInfo { + // I don't see how half of this information is useful with how the JRE system currently functions -figboot + pub availability: Availability, + pub manifest: DownloadInfo, + pub version: Version +} + +pub type JavaRuntimesManifest = HashMap<String, HashMap<String, Vec<JavaRuntimeInfo>>>; + +#[derive(Debug, Deserialize, Clone, Copy, Eq, PartialEq)] +#[serde(rename_all = "lowercase")] +pub enum FileType { + File, + Directory, + Link +} + +#[derive(Debug, Deserialize)] +pub struct JavaRuntimeFile { + #[serde(rename = "type")] + pub file_type: FileType, + #[serde(default)] + pub executable: bool, + + pub lzma: DownloadInfo, + pub raw: DownloadInfo +} + +#[derive(Debug, Deserialize)] +pub struct JavaRuntimeManifest { + pub files: HashMap<String, JavaRuntimeFile> +} |
