ruqu_neural_decoder/
error.rs1use thiserror::Error;
7
8pub type Result<T> = std::result::Result<T, NeuralDecoderError>;
10
11#[derive(Error, Debug)]
13pub enum NeuralDecoderError {
14 #[error("Invalid syndrome dimensions: expected {expected}x{expected}, got {actual_rows}x{actual_cols}")]
16 InvalidSyndromeDimension {
17 expected: usize,
19 actual_rows: usize,
21 actual_cols: usize,
23 },
24
25 #[error("Invalid embedding dimension: expected {expected}, got {actual}")]
27 InvalidEmbeddingDimension {
28 expected: usize,
30 actual: usize,
32 },
33
34 #[error("Invalid hidden state dimension: expected {expected}, got {actual}")]
36 InvalidHiddenDimension {
37 expected: usize,
39 actual: usize,
41 },
42
43 #[error("Embedding dimension {embed_dim} must be divisible by number of heads {num_heads}")]
45 InvalidAttentionHeads {
46 embed_dim: usize,
48 num_heads: usize,
50 },
51
52 #[error("Detector graph is empty")]
54 EmptyGraph,
55
56 #[error("Invalid detector index: {0}")]
58 InvalidDetector(usize),
59
60 #[error("Invalid boundary type: {0}")]
62 InvalidBoundary(String),
63
64 #[error("Decoding failed: {0}")]
66 DecodingFailed(String),
67
68 #[error("Feature fusion error: {0}")]
70 FusionError(String),
71
72 #[error("MinCut integration error: {0}")]
74 MinCutError(String),
75
76 #[error("Shape mismatch: expected {expected:?}, got {actual:?}")]
78 ShapeMismatch {
79 expected: Vec<usize>,
81 actual: Vec<usize>,
83 },
84
85 #[error("Numerical instability detected: {0}")]
87 NumericalInstability(String),
88
89 #[error("Configuration error: {0}")]
91 ConfigError(String),
92
93 #[error("Internal error: {0}")]
95 InternalError(String),
96}
97
98impl NeuralDecoderError {
99 pub fn syndrome_dim(expected: usize, rows: usize, cols: usize) -> Self {
101 Self::InvalidSyndromeDimension {
102 expected,
103 actual_rows: rows,
104 actual_cols: cols,
105 }
106 }
107
108 pub fn embed_dim(expected: usize, actual: usize) -> Self {
110 Self::InvalidEmbeddingDimension { expected, actual }
111 }
112
113 pub fn hidden_dim(expected: usize, actual: usize) -> Self {
115 Self::InvalidHiddenDimension { expected, actual }
116 }
117
118 pub fn attention_heads(embed_dim: usize, num_heads: usize) -> Self {
120 Self::InvalidAttentionHeads {
121 embed_dim,
122 num_heads,
123 }
124 }
125
126 pub fn shape_mismatch(expected: Vec<usize>, actual: Vec<usize>) -> Self {
128 Self::ShapeMismatch { expected, actual }
129 }
130
131 pub fn is_recoverable(&self) -> bool {
133 matches!(
134 self,
135 Self::InvalidDetector(_)
136 | Self::InvalidBoundary(_)
137 | Self::ConfigError(_)
138 )
139 }
140
141 pub fn is_dimension_error(&self) -> bool {
143 matches!(
144 self,
145 Self::InvalidSyndromeDimension { .. }
146 | Self::InvalidEmbeddingDimension { .. }
147 | Self::InvalidHiddenDimension { .. }
148 | Self::InvalidAttentionHeads { .. }
149 | Self::ShapeMismatch { .. }
150 )
151 }
152}
153
154impl From<ruvector_mincut::MinCutError> for NeuralDecoderError {
155 fn from(err: ruvector_mincut::MinCutError) -> Self {
156 Self::MinCutError(err.to_string())
157 }
158}
159
160impl From<String> for NeuralDecoderError {
161 fn from(msg: String) -> Self {
162 Self::InternalError(msg)
163 }
164}
165
166impl From<&str> for NeuralDecoderError {
167 fn from(msg: &str) -> Self {
168 Self::InternalError(msg.to_string())
169 }
170}
171
172#[cfg(test)]
173mod tests {
174 use super::*;
175
176 #[test]
177 fn test_error_display() {
178 let err = NeuralDecoderError::syndrome_dim(5, 3, 4);
179 assert!(err.to_string().contains("5"));
180 assert!(err.to_string().contains("3"));
181 assert!(err.to_string().contains("4"));
182
183 let err = NeuralDecoderError::embed_dim(128, 64);
184 assert!(err.to_string().contains("128"));
185 assert!(err.to_string().contains("64"));
186 }
187
188 #[test]
189 fn test_is_recoverable() {
190 assert!(NeuralDecoderError::InvalidDetector(0).is_recoverable());
191 assert!(NeuralDecoderError::InvalidBoundary("test".to_string()).is_recoverable());
192 assert!(!NeuralDecoderError::EmptyGraph.is_recoverable());
193 assert!(!NeuralDecoderError::DecodingFailed("test".to_string()).is_recoverable());
194 }
195
196 #[test]
197 fn test_is_dimension_error() {
198 assert!(NeuralDecoderError::syndrome_dim(5, 3, 4).is_dimension_error());
199 assert!(NeuralDecoderError::embed_dim(128, 64).is_dimension_error());
200 assert!(NeuralDecoderError::attention_heads(128, 3).is_dimension_error());
201 assert!(!NeuralDecoderError::EmptyGraph.is_dimension_error());
202 }
203
204 #[test]
205 fn test_from_string() {
206 let err: NeuralDecoderError = "test error".into();
207 assert!(matches!(err, NeuralDecoderError::InternalError(_)));
208 assert!(err.to_string().contains("test error"));
209 }
210}