oxigdal_analytics/
error.rs1use thiserror::Error;
7
8pub type Result<T> = std::result::Result<T, AnalyticsError>;
10
11#[derive(Debug, Error)]
13pub enum AnalyticsError {
14 #[error("Invalid input: {0}")]
16 InvalidInput(String),
17
18 #[error("Insufficient data: {0}")]
20 InsufficientData(String),
21
22 #[error("Convergence failed: {0}")]
24 ConvergenceError(String),
25
26 #[error("Numerical instability: {0}")]
28 NumericalInstability(String),
29
30 #[error("Matrix operation failed: {0}")]
32 MatrixError(String),
33
34 #[error("Dimension mismatch: expected {expected}, got {actual}")]
36 DimensionMismatch { expected: String, actual: String },
37
38 #[error("Invalid parameter '{param}': {reason}")]
40 InvalidParameter { param: String, reason: String },
41
42 #[error("Statistical test failed: {0}")]
44 StatisticalTestError(String),
45
46 #[error("Clustering failed: {0}")]
48 ClusteringError(String),
49
50 #[error("Interpolation failed: {0}")]
52 InterpolationError(String),
53
54 #[error("Time series analysis failed: {0}")]
56 TimeSeriesError(String),
57
58 #[error("Hotspot analysis failed: {0}")]
60 HotspotError(String),
61
62 #[error("Change detection failed: {0}")]
64 ChangeDetectionError(String),
65
66 #[error("Zonal statistics failed: {0}")]
68 ZonalStatsError(String),
69
70 #[error("Core error: {0}")]
72 CoreError(#[from] oxigdal_core::error::OxiGdalError),
73
74 #[error("SciRS2 error: {0}")]
76 SciRS2Error(String),
77
78 #[error("I/O error: {0}")]
80 IoError(#[from] std::io::Error),
81}
82
83impl AnalyticsError {
84 pub fn invalid_input(msg: impl Into<String>) -> Self {
86 Self::InvalidInput(msg.into())
87 }
88
89 pub fn insufficient_data(msg: impl Into<String>) -> Self {
91 Self::InsufficientData(msg.into())
92 }
93
94 pub fn convergence_error(msg: impl Into<String>) -> Self {
96 Self::ConvergenceError(msg.into())
97 }
98
99 pub fn numerical_instability(msg: impl Into<String>) -> Self {
101 Self::NumericalInstability(msg.into())
102 }
103
104 pub fn matrix_error(msg: impl Into<String>) -> Self {
106 Self::MatrixError(msg.into())
107 }
108
109 pub fn dimension_mismatch(expected: impl Into<String>, actual: impl Into<String>) -> Self {
111 Self::DimensionMismatch {
112 expected: expected.into(),
113 actual: actual.into(),
114 }
115 }
116
117 pub fn invalid_parameter(param: impl Into<String>, reason: impl Into<String>) -> Self {
119 Self::InvalidParameter {
120 param: param.into(),
121 reason: reason.into(),
122 }
123 }
124
125 pub fn statistical_test_error(msg: impl Into<String>) -> Self {
127 Self::StatisticalTestError(msg.into())
128 }
129
130 pub fn clustering_error(msg: impl Into<String>) -> Self {
132 Self::ClusteringError(msg.into())
133 }
134
135 pub fn interpolation_error(msg: impl Into<String>) -> Self {
137 Self::InterpolationError(msg.into())
138 }
139
140 pub fn time_series_error(msg: impl Into<String>) -> Self {
142 Self::TimeSeriesError(msg.into())
143 }
144
145 pub fn hotspot_error(msg: impl Into<String>) -> Self {
147 Self::HotspotError(msg.into())
148 }
149
150 pub fn change_detection_error(msg: impl Into<String>) -> Self {
152 Self::ChangeDetectionError(msg.into())
153 }
154
155 pub fn zonal_stats_error(msg: impl Into<String>) -> Self {
157 Self::ZonalStatsError(msg.into())
158 }
159
160 pub fn scirs2_error(msg: impl Into<String>) -> Self {
162 Self::SciRS2Error(msg.into())
163 }
164}
165
166#[cfg(test)]
167mod tests {
168 use super::*;
169
170 #[test]
171 fn test_error_creation() {
172 let err = AnalyticsError::invalid_input("test");
173 assert!(matches!(err, AnalyticsError::InvalidInput(_)));
174
175 let err = AnalyticsError::dimension_mismatch("3x3", "4x4");
176 assert!(matches!(err, AnalyticsError::DimensionMismatch { .. }));
177 }
178
179 #[test]
180 fn test_error_display() {
181 let err = AnalyticsError::invalid_input("invalid parameter value");
182 assert_eq!(format!("{}", err), "Invalid input: invalid parameter value");
183
184 let err = AnalyticsError::dimension_mismatch("3x3", "4x4");
185 assert_eq!(
186 format!("{}", err),
187 "Dimension mismatch: expected 3x3, got 4x4"
188 );
189 }
190}