1use thiserror::Error;
4
5#[derive(Error, Debug)]
7pub enum RezCoreError {
8 #[error("Version parsing error: {0}")]
9 VersionParse(String),
10
11 #[error("Version range error: {0}")]
12 VersionRange(String),
13
14 #[error("Package parsing error: {0}")]
15 PackageParse(String),
16
17 #[error("Requirement parsing error: {0}")]
18 RequirementParse(String),
19
20 #[error("Solver error: {0}")]
21 Solver(String),
22
23 #[error("Repository error: {0}")]
24 Repository(String),
25
26 #[error("Cache error: {0}")]
27 Cache(String),
28
29 #[error("IO error: {0}")]
30 Io(#[from] std::io::Error),
31
32 #[error("Serialization error: {0}")]
33 Serde(#[from] serde_json::Error),
34
35 #[error("Python error: {0}")]
36 Python(String),
37
38 #[error("Rex error: {0}")]
39 RexError(String),
40
41 #[error("Context error: {0}")]
42 ContextError(String),
43
44 #[error("Build error: {0}")]
45 BuildError(String),
46
47 #[error("Execution error: {0}")]
48 ExecutionError(String),
49
50 #[error("CLI error: {0}")]
51 CliError(String),
52
53 #[error("Configuration error: {0}")]
54 ConfigError(String),
55}
56
57pub type RezCoreResult<T> = Result<T, RezCoreError>;
59
60#[cfg(test)]
61mod tests {
62 use super::*;
63
64 #[test]
65 fn test_version_parse_error_display() {
66 let e = RezCoreError::VersionParse("bad version".to_string());
67 assert!(e.to_string().contains("bad version"));
68 assert!(e.to_string().contains("Version parsing error"));
69 }
70
71 #[test]
72 fn test_version_range_error_display() {
73 let e = RezCoreError::VersionRange("invalid range".to_string());
74 assert!(e.to_string().contains("invalid range"));
75 }
76
77 #[test]
78 fn test_package_parse_error_display() {
79 let e = RezCoreError::PackageParse("missing name".to_string());
80 assert!(e.to_string().contains("missing name"));
81 }
82
83 #[test]
84 fn test_requirement_parse_error_display() {
85 let e = RezCoreError::RequirementParse("bad req".to_string());
86 assert!(e.to_string().contains("bad req"));
87 assert!(e.to_string().contains("Requirement parsing error"));
88 }
89
90 #[test]
91 fn test_solver_error_display() {
92 let e = RezCoreError::Solver("conflict detected".to_string());
93 assert!(e.to_string().contains("conflict detected"));
94 assert!(e.to_string().contains("Solver error"));
95 }
96
97 #[test]
98 fn test_repository_error_display() {
99 let e = RezCoreError::Repository("not found".to_string());
100 assert!(e.to_string().contains("not found"));
101 }
102
103 #[test]
104 fn test_cache_error_display() {
105 let e = RezCoreError::Cache("cache miss".to_string());
106 assert!(e.to_string().contains("cache miss"));
107 }
108
109 #[test]
110 fn test_io_error_from() {
111 let io_err = std::io::Error::new(std::io::ErrorKind::NotFound, "file not found");
112 let rez_err: RezCoreError = io_err.into();
113 assert!(rez_err.to_string().contains("IO error"));
114 assert!(rez_err.to_string().contains("file not found"));
115 }
116
117 #[test]
118 fn test_serde_error_from() {
119 let bad_json = "{ invalid }";
120 let serde_err: Result<serde_json::Value, _> = serde_json::from_str(bad_json);
121 let rez_err: RezCoreError = serde_err.unwrap_err().into();
122 assert!(rez_err.to_string().contains("Serialization error"));
123 }
124
125 #[test]
126 fn test_rex_error_display() {
127 let e = RezCoreError::RexError("script failed".to_string());
128 assert!(e.to_string().contains("Rex error"));
129 assert!(e.to_string().contains("script failed"));
130 }
131
132 #[test]
133 fn test_context_error_display() {
134 let e = RezCoreError::ContextError("context not resolved".to_string());
135 assert!(e.to_string().contains("Context error"));
136 }
137
138 #[test]
139 fn test_build_error_display() {
140 let e = RezCoreError::BuildError("build failed".to_string());
141 assert!(e.to_string().contains("Build error"));
142 assert!(e.to_string().contains("build failed"));
143 }
144
145 #[test]
146 fn test_execution_error_display() {
147 let e = RezCoreError::ExecutionError("process exited 1".to_string());
148 assert!(e.to_string().contains("Execution error"));
149 }
150
151 #[test]
152 fn test_cli_error_display() {
153 let e = RezCoreError::CliError("unknown subcommand".to_string());
154 assert!(e.to_string().contains("CLI error"));
155 }
156
157 #[test]
158 fn test_config_error_display() {
159 let e = RezCoreError::ConfigError("missing packages_path".to_string());
160 assert!(e.to_string().contains("Configuration error"));
161 assert!(e.to_string().contains("missing packages_path"));
162 }
163
164 #[test]
165 fn test_error_is_debug() {
166 let e = RezCoreError::Solver("test".to_string());
167 let debug = format!("{e:?}");
168 assert!(!debug.is_empty());
169 }
170
171 #[test]
172 fn test_rez_core_result_ok() {
173 let result: RezCoreResult<i32> = Ok(42);
174 assert!(result.is_ok());
175 let val = match result {
176 Ok(v) => v,
177 Err(_) => unreachable!("result should be Ok"),
178 };
179 assert_eq!(val, 42);
180 }
181
182 #[test]
183 fn test_rez_core_result_err() {
184 let result: RezCoreResult<i32> = Err(RezCoreError::Solver("test".to_string()));
185 assert!(result.is_err());
186 }
187}