1use std::fmt;
8
9#[derive(Debug, Clone, PartialEq)]
23pub enum ContextError {
24 ConfigurationNotFound {
26 key: String,
28 },
29
30 InvalidConfiguration {
32 key: String,
34 reason: String,
36 },
37
38 InitializationFailed {
40 reason: String,
42 },
43
44 ConfigurationFileError {
46 message: String,
48 },
49
50 SerializationError {
52 message: String,
54 },
55
56 PropertyBindingError {
58 property: String,
60 reason: String,
62 },
63}
64
65impl fmt::Display for ContextError {
66 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67 match self {
68 ContextError::ConfigurationNotFound { key } => {
69 write!(f, "Configuration not found: {}", key)
70 }
71 ContextError::InvalidConfiguration { key, reason } => {
72 write!(f, "Invalid configuration for key '{}': {}", key, reason)
73 }
74 ContextError::InitializationFailed { reason } => {
75 write!(f, "Context initialization failed: {}", reason)
76 }
77 ContextError::ConfigurationFileError { message } => {
78 write!(f, "Configuration file error: {}", message)
79 }
80 ContextError::SerializationError { message } => {
81 write!(f, "Serialization error: {}", message)
82 }
83 ContextError::PropertyBindingError { property, reason } => {
84 write!(f, "Property binding error for '{}': {}", property, reason)
85 }
86 }
87 }
88}
89
90impl std::error::Error for ContextError {}
91
92impl ContextError {
93 pub fn configuration_not_found(key: impl Into<String>) -> Self {
107 Self::ConfigurationNotFound { key: key.into() }
108 }
109
110 pub fn invalid_configuration(key: impl Into<String>, reason: impl Into<String>) -> Self {
117 Self::InvalidConfiguration {
118 key: key.into(),
119 reason: reason.into(),
120 }
121 }
122
123 pub fn initialization_failed(reason: impl Into<String>) -> Self {
129 Self::InitializationFailed {
130 reason: reason.into(),
131 }
132 }
133
134 pub fn configuration_file_error(message: impl Into<String>) -> Self {
140 Self::ConfigurationFileError {
141 message: message.into(),
142 }
143 }
144
145 pub fn serialization_error(message: impl Into<String>) -> Self {
151 Self::SerializationError {
152 message: message.into(),
153 }
154 }
155
156 pub fn property_binding_error(property: impl Into<String>, reason: impl Into<String>) -> Self {
163 Self::PropertyBindingError {
164 property: property.into(),
165 reason: reason.into(),
166 }
167 }
168}
169
170pub type ContextResult<T> = Result<T, ContextError>;
175
176#[cfg(test)]
177mod tests {
178 use super::*;
179
180 #[test]
181 fn test_context_error_creation() {
182 let error = ContextError::configuration_not_found("test.key");
183 assert!(matches!(error, ContextError::ConfigurationNotFound { .. }));
184 assert_eq!(error.to_string(), "Configuration not found: test.key");
185 }
186
187 #[test]
188 fn test_invalid_configuration_error() {
189 let error = ContextError::invalid_configuration("port", "not a number");
190 assert!(matches!(error, ContextError::InvalidConfiguration { .. }));
191 assert_eq!(
192 error.to_string(),
193 "Invalid configuration for key 'port': not a number"
194 );
195 }
196
197 #[test]
198 fn test_initialization_failed_error() {
199 let error = ContextError::initialization_failed("missing required config");
200 assert!(matches!(error, ContextError::InitializationFailed { .. }));
201 assert_eq!(
202 error.to_string(),
203 "Context initialization failed: missing required config"
204 );
205 }
206
207 #[test]
208 fn test_configuration_file_error() {
209 let error = ContextError::configuration_file_error("file not found");
210 assert!(matches!(error, ContextError::ConfigurationFileError { .. }));
211 assert_eq!(
212 error.to_string(),
213 "Configuration file error: file not found"
214 );
215 }
216
217 #[test]
218 fn test_serialization_error() {
219 let error = ContextError::serialization_error("invalid TOML format");
220 assert!(matches!(error, ContextError::SerializationError { .. }));
221 assert_eq!(
222 error.to_string(),
223 "Serialization error: invalid TOML format"
224 );
225 }
226
227 #[test]
228 fn test_property_binding_error() {
229 let error = ContextError::property_binding_error("database.port", "type mismatch");
230 assert!(matches!(error, ContextError::PropertyBindingError { .. }));
231 assert_eq!(
232 error.to_string(),
233 "Property binding error for 'database.port': type mismatch"
234 );
235 }
236}