numrs2/error/
legacy.rs

1//! Legacy error system for backward compatibility
2//!
3//! This maintains the original NumRS2Error enum structure to ensure
4//! existing code continues to work without modification.
5
6use super::{ErrorCategory, ErrorContext, ErrorLocation, ErrorSeverity, OperationContext};
7use std::io;
8use thiserror::Error;
9
10/// NumRS2 error types (legacy structure for backward compatibility)
11#[derive(Error, Debug)]
12pub enum NumRs2Error {
13    #[error("Shape mismatch: expected {expected:?}, got {actual:?}")]
14    ShapeMismatch {
15        expected: Vec<usize>,
16        actual: Vec<usize>,
17    },
18
19    #[error("Dimension mismatch: {0}")]
20    DimensionMismatch(String),
21
22    #[error("Invalid operation: {0}")]
23    InvalidOperation(String),
24
25    #[error("Value error: {0}")]
26    ValueError(String),
27
28    #[error("Index error: {0}")]
29    IndexError(String),
30
31    #[error("BLAS error: code {0}")]
32    BlasError(i32),
33
34    #[error("LAPACK error: {0}")]
35    LapackError(String),
36
37    #[error("Conversion error: {0}")]
38    ConversionError(String),
39
40    #[error("Type cast error: {0}")]
41    TypeCastError(String),
42
43    #[error("Index out of bounds: {0}")]
44    IndexOutOfBounds(String),
45
46    #[error("Computation error: {0}")]
47    ComputationError(String),
48
49    #[error("Serialization error: {0}")]
50    SerializationError(String),
51
52    #[error("Deserialization error: {0}")]
53    DeserializationError(String),
54
55    #[error("I/O error: {0}")]
56    IOError(String),
57
58    #[error("Not implemented: {0}")]
59    NotImplemented(String),
60
61    #[error("Runtime error: {0}")]
62    RuntimeError(String),
63
64    #[error("Memory allocation failed: {0}")]
65    AllocationFailed(String),
66
67    #[error("Feature not enabled: {0}")]
68    FeatureNotEnabled(String),
69
70    // New hierarchical variants that integrate with the legacy system
71    #[error("{0}")]
72    Core(#[from] super::hierarchical::CoreError),
73
74    #[error("{0}")]
75    Computation(#[from] super::hierarchical::ComputationError),
76
77    #[error("{0}")]
78    Memory(#[from] super::hierarchical::MemoryError),
79
80    #[error("{0}")]
81    IO(#[from] super::hierarchical::IOError),
82}
83
84/// Result type for NumRS2 operations
85pub type Result<T> = std::result::Result<T, NumRs2Error>;
86
87/// Implement From<io::Error> for NumRs2Error
88impl From<io::Error> for NumRs2Error {
89    fn from(err: io::Error) -> Self {
90        NumRs2Error::IOError(err.to_string())
91    }
92}
93
94/// Implement From<Box<bincode::ErrorKind>> for NumRs2Error
95impl From<Box<bincode::ErrorKind>> for NumRs2Error {
96    fn from(err: Box<bincode::ErrorKind>) -> Self {
97        NumRs2Error::DeserializationError(err.to_string())
98    }
99}
100
101impl NumRs2Error {
102    /// Get the error category for this error
103    pub fn category(&self) -> ErrorCategory {
104        match self {
105            NumRs2Error::Core(_) => ErrorCategory::Core,
106            NumRs2Error::Computation(_) => ErrorCategory::Computation,
107            NumRs2Error::Memory(_) => ErrorCategory::Memory,
108            NumRs2Error::IO(_) => ErrorCategory::IO,
109
110            // Legacy variants mapped to categories
111            NumRs2Error::DimensionMismatch(_)
112            | NumRs2Error::InvalidOperation(_)
113            | NumRs2Error::ValueError(_)
114            | NumRs2Error::IndexError(_)
115            | NumRs2Error::IndexOutOfBounds(_)
116            | NumRs2Error::ConversionError(_)
117            | NumRs2Error::TypeCastError(_)
118            | NumRs2Error::ShapeMismatch { .. } => ErrorCategory::Core,
119
120            NumRs2Error::ComputationError(_)
121            | NumRs2Error::BlasError(_)
122            | NumRs2Error::LapackError(_) => ErrorCategory::Computation,
123
124            NumRs2Error::AllocationFailed(_) => ErrorCategory::Memory,
125
126            NumRs2Error::SerializationError(_)
127            | NumRs2Error::DeserializationError(_)
128            | NumRs2Error::IOError(_) => ErrorCategory::IO,
129
130            NumRs2Error::NotImplemented(_)
131            | NumRs2Error::RuntimeError(_)
132            | NumRs2Error::FeatureNotEnabled(_) => ErrorCategory::Core,
133        }
134    }
135
136    /// Get the severity level of this error
137    pub fn severity(&self) -> ErrorSeverity {
138        match self {
139            NumRs2Error::Core(e) => e.severity(),
140            NumRs2Error::Computation(e) => e.severity(),
141            NumRs2Error::Memory(e) => e.severity(),
142            NumRs2Error::IO(e) => e.severity(),
143
144            // Legacy variants with default severities
145            NumRs2Error::AllocationFailed(_) => ErrorSeverity::Critical,
146            NumRs2Error::LapackError(_) | NumRs2Error::BlasError(_) => ErrorSeverity::High,
147            NumRs2Error::DimensionMismatch(_) | NumRs2Error::ShapeMismatch { .. } => {
148                ErrorSeverity::High
149            }
150            NumRs2Error::IndexOutOfBounds(_) | NumRs2Error::IndexError(_) => ErrorSeverity::Medium,
151            NumRs2Error::NotImplemented(_) | NumRs2Error::FeatureNotEnabled(_) => {
152                ErrorSeverity::Low
153            }
154            _ => ErrorSeverity::Medium,
155        }
156    }
157
158    /// Check if this error is recoverable
159    pub fn is_recoverable(&self) -> bool {
160        match self.severity() {
161            ErrorSeverity::Critical => false,
162            ErrorSeverity::High => false,
163            ErrorSeverity::Medium => true,
164            ErrorSeverity::Low => true,
165        }
166    }
167
168    /// Create a new error with context information
169    pub fn with_context<C: Into<OperationContext>>(self, context: C) -> ErrorContext<Self> {
170        ErrorContext::new(self, context.into())
171    }
172
173    /// Create a new error with location information
174    pub fn at_location(self, location: ErrorLocation) -> ErrorContext<Self> {
175        ErrorContext::new(self, OperationContext::default()).with_location(location)
176    }
177}