1use std::path::{Path, PathBuf};
2use error::{JavaError, JavaErrorKind, Result};
3use version::JavaVersion;
4use crate::{os::{process::ProgramPathFinder, OsAbstraction}, utils::choice_by_os};
5
6pub mod error;
7pub mod version;
8
9pub const JAVA_SEPARATOR: &str = if cfg!(target_os = "windows") { ";" } else { ":" };
10
11#[derive(Debug, Clone)]
12pub struct Java {
13 base_path: PathBuf,
14 version: JavaVersion
15}
16
17impl TryFrom<String> for Java {
18 type Error = JavaError;
19
20 fn try_from(value: String) -> Result<Self> {
21 Self::new(Path::new(&value).to_path_buf())
22 }
23}
24
25impl Java {
26 pub fn new(base_path: PathBuf) -> Result<Self> {
27 if !base_path.is_dir() {
28 return Err(JavaError::new(JavaErrorKind::NotFound));
29 }
30
31 let version = JavaVersion::get_verison(&base_path)?;
32
33 Ok(Self {
34 base_path,
35 version
36 })
37 }
38
39 pub fn find() -> Result<Self> {
41 if let Ok(path) = std::env::var("JAVA_HOME") {
43 return Java::try_from(path);
44 }
45
46 let java_err = JavaError::new(JavaErrorKind::InvalidJavaFolderStructure);
50
51 let path = OsAbstraction::find_path("java")?;
52
53 let parent = path.ancestors()
54 .next().ok_or(java_err.clone())?
55 .file_name().ok_or(java_err.clone())?
56 .to_str().ok_or(java_err.clone())?;
57
58 if parent != "bin" {
59 return Err(java_err);
60 }
61
62 Self::new(path)
63 }
64
65 pub fn get_java(&self) -> Result<PathBuf> {
66 let path = self.base_path
67 .join("bin")
68 .join(choice_by_os("java", "java.exe"));
69
70 if !path.is_file() {
71 return Err(JavaError::new(JavaErrorKind::NotFound))
72 }
73
74 Ok(path)
75 }
76
77 pub fn get_javaw(&self) -> Result<PathBuf> {
78 let path = self.base_path
79 .join("bin")
80 .join(choice_by_os("java", "javaw.exe"));
82
83 if !path.is_file() {
84 return Err(JavaError::new(JavaErrorKind::NotFound))
85 }
86
87 Ok(path)
88 }
89
90 pub fn version(&self) -> &JavaVersion {
91 &self.version
92 }
93
94 pub fn is_version_equal(&self, needed_version: u8) -> Result<()> {
102 if self.version.main_version() != needed_version {
103 return Err(JavaError::new(JavaErrorKind::DifferentVersion))
104 }
105
106 Ok(())
107 }
108
109 pub fn is_version_at_least(&self, needed_version: u8) -> Result<()> {
117 if self.version.main_version() != needed_version {
118 return Err(JavaError::new(JavaErrorKind::DifferentVersion))
119 }
120
121 Ok(())
122 }
123}