use crate::error::{PlatformError, RealTimeError, SafetyError};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CRDTError {
OutOfMemory,
InvalidAlignment,
BufferOverflow,
ConfigurationExceeded,
DeadlineExceeded,
LockTimeout,
InterruptOverrun,
PlatformSpecificTimeout,
SafetyViolation,
IntegrityCheckFailed,
InvalidSafetyLevel,
DomainSpecificError,
ClockSkew,
InvalidMerge,
CausalityViolation,
NodeCountExceeded,
InvalidNodeId,
InvalidState,
InvalidOperation,
PlatformNotSupported(PlatformError),
HardwareFeatureUnavailable,
ConfigurationMismatch,
RealTimeViolation(RealTimeError),
}
impl CRDTError {
pub const fn is_recoverable(&self) -> bool {
match self {
Self::OutOfMemory
| Self::BufferOverflow
| Self::ConfigurationExceeded
| Self::SafetyViolation
| Self::IntegrityCheckFailed
| Self::CausalityViolation
| Self::PlatformNotSupported(_)
| Self::ConfigurationMismatch => false,
Self::InvalidAlignment
| Self::DeadlineExceeded
| Self::LockTimeout
| Self::InterruptOverrun
| Self::PlatformSpecificTimeout
| Self::InvalidSafetyLevel
| Self::DomainSpecificError
| Self::ClockSkew
| Self::InvalidMerge
| Self::NodeCountExceeded
| Self::InvalidNodeId
| Self::InvalidState
| Self::InvalidOperation
| Self::HardwareFeatureUnavailable
| Self::RealTimeViolation(_) => true,
}
}
pub const fn is_safety_critical(&self) -> bool {
match self {
Self::SafetyViolation
| Self::IntegrityCheckFailed
| Self::CausalityViolation
| Self::BufferOverflow => true,
_ => false,
}
}
pub const fn is_realtime_error(&self) -> bool {
match self {
Self::DeadlineExceeded
| Self::LockTimeout
| Self::InterruptOverrun
| Self::PlatformSpecificTimeout
| Self::RealTimeViolation(_) => true,
_ => false,
}
}
pub const fn is_platform_error(&self) -> bool {
match self {
Self::PlatformNotSupported(_)
| Self::HardwareFeatureUnavailable
| Self::PlatformSpecificTimeout => true,
_ => false,
}
}
pub const fn category(&self) -> &'static str {
match self {
Self::OutOfMemory
| Self::InvalidAlignment
| Self::BufferOverflow
| Self::ConfigurationExceeded => "Memory",
Self::DeadlineExceeded
| Self::LockTimeout
| Self::InterruptOverrun
| Self::PlatformSpecificTimeout
| Self::RealTimeViolation(_) => "RealTime",
Self::SafetyViolation
| Self::IntegrityCheckFailed
| Self::InvalidSafetyLevel
| Self::DomainSpecificError => "Safety",
Self::ClockSkew
| Self::InvalidMerge
| Self::CausalityViolation
| Self::NodeCountExceeded
| Self::InvalidNodeId
| Self::InvalidState
| Self::InvalidOperation => "CRDT",
Self::PlatformNotSupported(_)
| Self::HardwareFeatureUnavailable
| Self::ConfigurationMismatch => "Platform",
}
}
}
impl From<SafetyError> for CRDTError {
fn from(_error: SafetyError) -> Self {
CRDTError::SafetyViolation
}
}
impl From<PlatformError> for CRDTError {
fn from(error: PlatformError) -> Self {
Self::PlatformNotSupported(error)
}
}
impl From<RealTimeError> for CRDTError {
fn from(error: RealTimeError) -> Self {
Self::RealTimeViolation(error)
}
}
pub type CRDTResult<T> = Result<T, CRDTError>;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_classification() {
assert!(!CRDTError::OutOfMemory.is_recoverable());
assert!(CRDTError::DeadlineExceeded.is_recoverable());
assert!(CRDTError::IntegrityCheckFailed.is_safety_critical());
assert!(!CRDTError::ClockSkew.is_safety_critical());
assert!(CRDTError::DeadlineExceeded.is_realtime_error());
assert!(!CRDTError::OutOfMemory.is_realtime_error());
assert!(CRDTError::HardwareFeatureUnavailable.is_platform_error());
assert!(!CRDTError::InvalidMerge.is_platform_error());
}
#[test]
fn test_error_categories() {
assert_eq!(CRDTError::OutOfMemory.category(), "Memory");
assert_eq!(CRDTError::DeadlineExceeded.category(), "RealTime");
assert_eq!(CRDTError::IntegrityCheckFailed.category(), "Safety");
assert_eq!(CRDTError::ClockSkew.category(), "CRDT");
assert_eq!(CRDTError::HardwareFeatureUnavailable.category(), "Platform");
}
}