mc_launcher/java/
version.rs

1use std::{path::Path, process::Command};
2use crate::{java::error::{JavaError, JavaErrorKind}, utils::choice_by_os};
3use super::error::Result;
4
5/// https://www.tpointtech.com/java-9-new-version-string-scheme
6#[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  // TODO @ its looks weird
22  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  /// 7, 8, 9, 11, 16, 17, 18, etc
59  pub fn main_version(&self) -> u8 {
60    if self.major == 1 {
61      return self.minor;
62    }
63
64    self.major
65  }
66}