1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
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
}
}
}
|