use std::fmt;
#[derive(Debug, Clone, PartialEq)]
pub enum ContextError {
ConfigurationNotFound {
key: String,
},
InvalidConfiguration {
key: String,
reason: String,
},
InitializationFailed {
reason: String,
},
ConfigurationFileError {
message: String,
},
SerializationError {
message: String,
},
PropertyBindingError {
property: String,
reason: String,
},
}
impl fmt::Display for ContextError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ContextError::ConfigurationNotFound { key } => {
write!(f, "Configuration not found: {}", key)
}
ContextError::InvalidConfiguration { key, reason } => {
write!(f, "Invalid configuration for key '{}': {}", key, reason)
}
ContextError::InitializationFailed { reason } => {
write!(f, "Context initialization failed: {}", reason)
}
ContextError::ConfigurationFileError { message } => {
write!(f, "Configuration file error: {}", message)
}
ContextError::SerializationError { message } => {
write!(f, "Serialization error: {}", message)
}
ContextError::PropertyBindingError { property, reason } => {
write!(f, "Property binding error for '{}': {}", property, reason)
}
}
}
}
impl std::error::Error for ContextError {}
impl ContextError {
pub fn configuration_not_found(key: impl Into<String>) -> Self {
Self::ConfigurationNotFound { key: key.into() }
}
pub fn invalid_configuration(key: impl Into<String>, reason: impl Into<String>) -> Self {
Self::InvalidConfiguration {
key: key.into(),
reason: reason.into(),
}
}
pub fn initialization_failed(reason: impl Into<String>) -> Self {
Self::InitializationFailed {
reason: reason.into(),
}
}
pub fn configuration_file_error(message: impl Into<String>) -> Self {
Self::ConfigurationFileError {
message: message.into(),
}
}
pub fn serialization_error(message: impl Into<String>) -> Self {
Self::SerializationError {
message: message.into(),
}
}
pub fn property_binding_error(property: impl Into<String>, reason: impl Into<String>) -> Self {
Self::PropertyBindingError {
property: property.into(),
reason: reason.into(),
}
}
}
pub type ContextResult<T> = Result<T, ContextError>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_context_error_creation() {
let error = ContextError::configuration_not_found("test.key");
assert!(matches!(error, ContextError::ConfigurationNotFound { .. }));
assert_eq!(error.to_string(), "Configuration not found: test.key");
}
#[test]
fn test_invalid_configuration_error() {
let error = ContextError::invalid_configuration("port", "not a number");
assert!(matches!(error, ContextError::InvalidConfiguration { .. }));
assert_eq!(
error.to_string(),
"Invalid configuration for key 'port': not a number"
);
}
#[test]
fn test_initialization_failed_error() {
let error = ContextError::initialization_failed("missing required config");
assert!(matches!(error, ContextError::InitializationFailed { .. }));
assert_eq!(
error.to_string(),
"Context initialization failed: missing required config"
);
}
#[test]
fn test_configuration_file_error() {
let error = ContextError::configuration_file_error("file not found");
assert!(matches!(error, ContextError::ConfigurationFileError { .. }));
assert_eq!(
error.to_string(),
"Configuration file error: file not found"
);
}
#[test]
fn test_serialization_error() {
let error = ContextError::serialization_error("invalid TOML format");
assert!(matches!(error, ContextError::SerializationError { .. }));
assert_eq!(
error.to_string(),
"Serialization error: invalid TOML format"
);
}
#[test]
fn test_property_binding_error() {
let error = ContextError::property_binding_error("database.port", "type mismatch");
assert!(matches!(error, ContextError::PropertyBindingError { .. }));
assert_eq!(
error.to_string(),
"Property binding error for 'database.port': type mismatch"
);
}
}