use thiserror::Error;
pub type Result<T> = std::result::Result<T, LoopError>;
#[derive(Error, Debug, Clone, PartialEq)]
#[allow(missing_docs)]
pub enum LoopError {
#[error("Strange loop failed to converge after {iterations} iterations")]
ConvergenceFailure { iterations: usize },
#[error("Strange loop timed out after {duration_ns}ns")]
TimeoutError { duration_ns: u128 },
#[error("Lipschitz constant violation: measured L={measured:.6} > limit={limit:.6}")]
LipschitzViolation { measured: f64, limit: f64 },
#[error("Invalid policy parameters: {message}")]
InvalidPolicy { message: String },
#[error("Quantum state error: {message}")]
QuantumError { message: String },
#[error("Consciousness calculation failed: {message}")]
ConsciousnessError { message: String },
#[error("Mathematical error: {message}")]
MathError { message: String },
#[error("Memory allocation failed: {message}")]
MemoryError { message: String },
#[error("Concurrency error: {message}")]
ConcurrencyError { message: String },
#[cfg(feature = "wasm")]
#[error("WASM error: {message}")]
WasmError { message: String },
#[cfg(feature = "simd")]
#[error("SIMD operation failed: {message}")]
SimdError { message: String },
}
impl LoopError {
pub fn convergence_failure(iterations: usize) -> Self {
Self::ConvergenceFailure { iterations }
}
pub fn timeout(duration_ns: u128) -> Self {
Self::TimeoutError { duration_ns }
}
pub fn lipschitz_violation(measured: f64, limit: f64) -> Self {
Self::LipschitzViolation { measured, limit }
}
pub fn invalid_policy(message: impl Into<String>) -> Self {
Self::InvalidPolicy { message: message.into() }
}
pub fn quantum_error(message: impl Into<String>) -> Self {
Self::QuantumError { message: message.into() }
}
pub fn consciousness_error(message: impl Into<String>) -> Self {
Self::ConsciousnessError { message: message.into() }
}
pub fn math_error(message: impl Into<String>) -> Self {
Self::MathError { message: message.into() }
}
pub fn memory_error(message: impl Into<String>) -> Self {
Self::MemoryError { message: message.into() }
}
pub fn concurrency_error(message: impl Into<String>) -> Self {
Self::ConcurrencyError { message: message.into() }
}
pub fn is_recoverable(&self) -> bool {
matches!(
self,
Self::ConvergenceFailure { .. } |
Self::TimeoutError { .. } |
Self::LipschitzViolation { .. }
)
}
pub fn is_fatal(&self) -> bool {
!self.is_recoverable()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_creation() {
let error = LoopError::convergence_failure(1000);
assert!(matches!(error, LoopError::ConvergenceFailure { iterations: 1000 }));
assert!(error.is_recoverable());
assert!(!error.is_fatal());
}
#[test]
fn test_error_display() {
let error = LoopError::timeout(5_000_000);
assert_eq!(error.to_string(), "Strange loop timed out after 5000000ns");
}
#[test]
fn test_lipschitz_violation() {
let error = LoopError::lipschitz_violation(1.2, 1.0);
assert!(matches!(
error,
LoopError::LipschitzViolation { measured, limit } if measured == 1.2 && limit == 1.0
));
}
}