1use std::fmt;
4use std::io;
5
6#[derive(Debug)]
8pub enum JavaError {
9 InvalidJavaPath(String),
11
12 NotFound(String),
14
15 StaleRegistryEntry(String),
17
18 IoError(io::Error),
20
21 ExecuteError(String),
23
24 RuntimeError(String),
26
27 ExecutionFailed(String),
29
30 DownloadError(String),
32
33 ExtractError(String),
35
36 Other(String),
38}
39
40impl fmt::Display for JavaError {
41 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
42 match self {
43 JavaError::InvalidJavaPath(msg) => write!(f, "Invalid Java path: {}", msg),
44 JavaError::NotFound(msg) => write!(f, "Not found: {}", msg),
45 JavaError::StaleRegistryEntry(msg) => write!(f, "Stale registry entry: {}", msg),
46 JavaError::IoError(err) => write!(f, "IO error: {}", err),
47 JavaError::ExecuteError(msg) => write!(f, "Execute error: {}", msg),
48 JavaError::RuntimeError(msg) => write!(f, "Runtime error: {}", msg),
49 JavaError::ExecutionFailed(msg) => write!(f, "Execution failed: {}", msg),
50 JavaError::DownloadError(msg) => write!(f, "Download error: {}", msg),
51 JavaError::ExtractError(msg) => write!(f, "Extraction error: {}", msg),
52 JavaError::Other(msg) => write!(f, "Other error: {}", msg),
53 }
54 }
55}
56
57impl std::error::Error for JavaError {
58 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
59 match self {
60 JavaError::IoError(err) => Some(err),
61 _ => None,
62 }
63 }
64}
65
66impl From<io::Error> for JavaError {
67 fn from(err: io::Error) -> Self {
68 JavaError::IoError(err)
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75 use std::error::Error;
76
77 #[test]
78 fn test_display_invalid_path() {
79 let err = JavaError::InvalidJavaPath("bad/path".into());
80 assert_eq!(err.to_string(), "Invalid Java path: bad/path");
81 }
82
83 #[test]
84 fn test_display_not_found() {
85 let err = JavaError::NotFound("missing.exe".into());
86 assert_eq!(err.to_string(), "Not found: missing.exe");
87 }
88
89 #[test]
90 fn test_display_stale_registry() {
91 let err = JavaError::StaleRegistryEntry("HKLM\\..".into());
92 assert_eq!(err.to_string(), "Stale registry entry: HKLM\\..");
93 }
94
95 #[test]
96 fn test_display_execution_failed() {
97 let err = JavaError::ExecutionFailed("exit code 1".into());
98 assert_eq!(err.to_string(), "Execution failed: exit code 1");
99 }
100
101 #[test]
102 fn test_display_extract_error() {
103 let err = JavaError::ExtractError("corrupt archive".into());
104 assert_eq!(err.to_string(), "Extraction error: corrupt archive");
105 }
106
107 #[test]
108 fn test_display_download_error() {
109 let err = JavaError::DownloadError("network".into());
110 assert_eq!(err.to_string(), "Download error: network");
111 }
112
113 #[test]
114 fn test_from_io_error() {
115 let io_err = io::Error::new(io::ErrorKind::NotFound, "file missing");
116 let java_err: JavaError = io_err.into();
117 assert!(matches!(java_err, JavaError::IoError(_)));
118 assert!(java_err.to_string().contains("IO error"));
119 }
120
121 #[test]
122 fn test_error_source_io() {
123 let io_err = io::Error::new(io::ErrorKind::PermissionDenied, "denied");
124 let java_err = JavaError::IoError(io_err);
125 assert!(java_err.source().is_some());
126 }
127
128 #[test]
129 fn test_error_source_other_variants() {
130 let err = JavaError::Other("msg".into());
131 assert!(err.source().is_none());
132 }
133
134 #[test]
135 fn test_debug_format() {
136 let err = JavaError::ExecuteError("boom".into());
137 let debug = format!("{err:?}");
138 assert!(debug.contains("ExecuteError"));
139 assert!(debug.contains("boom"));
140 }
141}