mc_launcher/java/
version.rs1use std::{path::Path, process::Command};
2use crate::{java::error::{JavaError, JavaErrorKind}, utils::choice_by_os};
3use super::error::Result;
4
5#[derive(Debug, Clone)]
7pub struct JavaVersion {
8 major: u8,
9 minor: u8,
10 #[allow(unused)]
11 security: u8,
12}
13
14macro_rules! get_item {
15 ($i:ident, $j:expr) => {
16 *$i.get($j).ok_or(JavaError::new(JavaErrorKind::OutputReadError))?
17 }
18}
19
20impl JavaVersion {
21 pub fn get_verison(java_base_path: &Path) -> Result<Self> {
23 let java_executable = java_base_path.join("bin")
24 .join(choice_by_os("java", "java.exe"));
25
26 let output = Command::new(java_executable)
27 .arg("-version")
28 .output()
29 .map_err(|e| JavaError::new_with_details(JavaErrorKind::OutputReadError, e.to_string()))?;
30
31 let version = String::from_utf8_lossy(&output.stderr)
32 .to_string();
33
34 let version_line = version
35 .lines()
36 .next()
37 .ok_or(JavaError::new_with_details(JavaErrorKind::OutputReadError, String::from("No client line")))?;
38
39 let version = version_line
40 .split_whitespace()
41 .find(|s| s.starts_with('"'))
42 .ok_or(JavaError::new_with_details(JavaErrorKind::OutputReadError, String::from("Unable to get Java's version")))?
43 .trim_matches('"')
44 .split('.');
45
46 let version_parts = version.collect::<Vec<&str>>()
47 .iter()
48 .map(|e| e.parse().unwrap_or_default())
49 .collect::<Vec<u8>>();
50
51 Ok(Self {
52 major: get_item!(version_parts, 0),
53 minor: get_item!(version_parts, 1),
54 security: get_item!(version_parts, 2),
55 })
56 }
57
58 pub fn main_version(&self) -> u8 {
60 if self.major == 1 {
61 return self.minor;
62 }
63
64 self.major
65 }
66}