1use thiserror::Error;
7
8#[derive(Error, Debug)]
10pub enum QearError {
11 #[error("Reservoir initialization error: {0}")]
13 ReservoirInit(String),
14
15 #[error("Reservoir evolution error: {0}")]
17 ReservoirEvolution(String),
18
19 #[error("Quantum state error: {0}")]
21 QuantumState(String),
22
23 #[error("Attention computation error: {0}")]
25 AttentionComputation(String),
26
27 #[error("Feature extraction error: {0}")]
29 FeatureExtraction(String),
30
31 #[error("Time series error: {0}")]
33 TimeSeries(String),
34
35 #[error("Training error: {0}")]
37 Training(String),
38
39 #[error("Dimension mismatch: expected {expected}, got {got}")]
41 DimensionMismatch {
42 expected: usize,
44 got: usize,
46 },
47
48 #[error("Invalid parameter '{name}': {reason}")]
50 InvalidParameter {
51 name: String,
53 reason: String,
55 },
56
57 #[error("Numerical instability: {0}")]
59 NumericalInstability(String),
60
61 #[error("Insufficient data: need at least {needed}, got {got}")]
63 InsufficientData {
64 needed: usize,
66 got: usize,
68 },
69
70 #[error("Model not trained: {0}")]
72 NotTrained(String),
73
74 #[error("Serialization error: {0}")]
76 Serialization(String),
77}
78
79pub type QearResult<T> = Result<T, QearError>;
81
82impl QearError {
83 pub fn reservoir_init(msg: impl Into<String>) -> Self {
85 QearError::ReservoirInit(msg.into())
86 }
87
88 pub fn reservoir_evolution(msg: impl Into<String>) -> Self {
90 QearError::ReservoirEvolution(msg.into())
91 }
92
93 pub fn quantum_state(msg: impl Into<String>) -> Self {
95 QearError::QuantumState(msg.into())
96 }
97
98 pub fn attention_computation(msg: impl Into<String>) -> Self {
100 QearError::AttentionComputation(msg.into())
101 }
102
103 pub fn feature_extraction(msg: impl Into<String>) -> Self {
105 QearError::FeatureExtraction(msg.into())
106 }
107
108 pub fn time_series(msg: impl Into<String>) -> Self {
110 QearError::TimeSeries(msg.into())
111 }
112
113 pub fn training(msg: impl Into<String>) -> Self {
115 QearError::Training(msg.into())
116 }
117
118 pub fn dimension_mismatch(expected: usize, got: usize) -> Self {
120 QearError::DimensionMismatch { expected, got }
121 }
122
123 pub fn invalid_parameter(name: impl Into<String>, reason: impl Into<String>) -> Self {
125 QearError::InvalidParameter {
126 name: name.into(),
127 reason: reason.into(),
128 }
129 }
130
131 pub fn numerical_instability(msg: impl Into<String>) -> Self {
133 QearError::NumericalInstability(msg.into())
134 }
135
136 pub fn insufficient_data(needed: usize, got: usize) -> Self {
138 QearError::InsufficientData { needed, got }
139 }
140
141 pub fn not_trained(msg: impl Into<String>) -> Self {
143 QearError::NotTrained(msg.into())
144 }
145}
146
147#[cfg(test)]
148mod tests {
149 use super::*;
150
151 #[test]
152 fn test_error_display() {
153 let err = QearError::reservoir_init("test error");
154 assert!(err.to_string().contains("test error"));
155 }
156
157 #[test]
158 fn test_dimension_mismatch() {
159 let err = QearError::dimension_mismatch(10, 5);
160 assert!(err.to_string().contains("expected 10"));
161 assert!(err.to_string().contains("got 5"));
162 }
163
164 #[test]
165 fn test_invalid_parameter() {
166 let err = QearError::invalid_parameter("spectral_radius", "must be positive");
167 assert!(err.to_string().contains("spectral_radius"));
168 assert!(err.to_string().contains("must be positive"));
169 }
170}