Skip to main content

scirs2_core/
error_templates.rs

1//! Standardized error message templates for consistent error reporting
2//!
3//! This module provides template functions for generating consistent error
4//! messages across the entire codebase.
5
6use std::fmt::Display;
7
8/// Generate an error message for dimension mismatch
9#[allow(dead_code)]
10pub fn dimension_mismatch(operation: &str, expected: impl Display, actual: impl Display) -> String {
11    format!("{operation}: dimension mismatch (expected: {expected}, actual: {actual})")
12}
13
14/// Generate an error message for shape mismatch in array operations
15#[allow(dead_code)]
16pub fn shape_mismatch(operation: &str, shape1: &[usize], shape2: &[usize]) -> String {
17    format!("{operation}: incompatible shapes ({shape1:?} vs {shape2:?})")
18}
19
20/// Generate an error message for invalid parameter values
21#[allow(dead_code)]
22pub fn value(param_name: &str, constraint: &str, actualvalue: impl Display) -> String {
23    format!("Parameter '{param_name}': {constraint} (got: {actualvalue})")
24}
25
26/// Generate an error message for out of bounds access
27#[allow(dead_code)]
28pub fn index(index: usize, length: usize) -> String {
29    format!("Index out of bounds: index {index} is invalid for length {length}")
30}
31
32/// Generate an error message for empty input
33#[allow(dead_code)]
34pub fn empty_input(operation: &str) -> String {
35    format!("{operation}: input array/collection is empty")
36}
37
38/// Generate an error message for numerical computation errors
39#[allow(dead_code)]
40pub fn numericalerror(operation: &str, issue: &str) -> String {
41    format!("{operation}: {issue} - check input values for numerical issues")
42}
43
44/// Generate an error message for convergence failures
45#[allow(dead_code)]
46pub fn algorithm(algorithm: &str, iterations: usize, tolerance: impl Display) -> String {
47    format!(
48        "{algorithm}: failed to converge after {iterations} iterations (tolerance: {tolerance})"
49    )
50}
51
52/// Generate an error message for not implemented features
53#[allow(dead_code)]
54pub fn feature(feature: &str) -> String {
55    format!("Feature not implemented: {feature}")
56}
57
58/// Generate an error message for invalid array dimensions
59#[allow(dead_code)]
60pub fn dims(operation: &str, requirement: &str, actualdims: &[usize]) -> String {
61    format!("{operation}: {requirement} (got: {actualdims:?})")
62}
63
64/// Generate an error message for domain errors
65#[allow(dead_code)]
66pub fn desc(valuedesc: &str, constraint: &str, value: impl Display) -> String {
67    format!("{valuedesc} must be {constraint} (got: {value})")
68}
69
70/// Generate an error message for allocation failures
71#[allow(dead_code)]
72pub fn allocationerror(size: usize, elementtype: &str) -> String {
73    format!("Failed to allocate memory for {size} elements of type {elementtype}")
74}
75
76/// Generate an error message for file I/O errors
77#[allow(dead_code)]
78pub fn ioerror(operation: &str, path: &str, details: &str) -> String {
79    format!("{operation} failed for '{path}': {details}")
80}
81
82/// Generate an error message for parse errors
83#[allow(dead_code)]
84pub fn parseerror(typename: &str, input: &str, reason: &str) -> String {
85    format!("Failed to parse '{input}' as {typename}: {reason}")
86}
87
88/// Generate an error message for invalid state
89#[allow(dead_code)]
90pub fn state(object: &str, expected_state: &str, actualstate: &str) -> String {
91    format!("{object} is in invalid state: expected {expected_state}, but was {actualstate}")
92}
93
94/// Generate an error message with recovery suggestion
95#[allow(dead_code)]
96pub fn msg(errormsg: &str, suggestion: &str) -> String {
97    format!("{errormsg}\nSuggestion: {suggestion}")
98}
99
100/// Common parameter constraints
101pub mod constraints {
102    /// Generate constraint message for positive values
103    pub fn positive() -> &'static str {
104        "must be positive (> 0)"
105    }
106
107    /// Generate constraint message for non-negative values
108    pub fn non_negative() -> &'static str {
109        "must be non-negative (>= 0)"
110    }
111
112    /// Generate constraint message for probability values
113    pub fn probability() -> &'static str {
114        "must be a valid probability in [0, 1]"
115    }
116
117    /// Generate constraint message for finite values
118    pub fn finite() -> &'static str {
119        "must be finite (not NaN or infinite)"
120    }
121
122    /// Generate constraint message for non-empty
123    pub fn non_empty() -> &'static str {
124        "must not be empty"
125    }
126
127    /// Generate constraint message for square matrix
128    pub fn squarematrix() -> &'static str {
129        "must be a square matrix"
130    }
131
132    /// Generate constraint message for positive definite matrix
133    pub fn positive_definite() -> &'static str {
134        "must be a positive definite matrix"
135    }
136}
137
138#[cfg(test)]
139mod tests {
140    use super::*;
141
142    #[test]
143    fn test_dimension_mismatch() {
144        let msg = dimension_mismatch("matrix multiplication", "3x4", "5x3");
145        assert_eq!(
146            msg,
147            "matrix multiplication: dimension mismatch (expected: 3x4, actual: 5x3)"
148        );
149    }
150
151    #[test]
152    fn testshape_mismatch() {
153        let msg = shape_mismatch("element-wise operation", &[3, 4], &[3, 5]);
154        assert_eq!(
155            msg,
156            "element-wise operation: incompatible shapes ([3, 4] vs [3, 5])"
157        );
158    }
159
160    // #[test]
161    // fn test_invalid_parameter() {
162    //     let msg = invalid_parameter("alpha", constraints::positive(), -0.5);
163    //     assert_eq!(msg, "Parameter 'alpha': must be positive (> 0) (got: -0.5)");
164    // }
165
166    // #[test]
167    // fn test_with_suggestion() {
168    //     let error = domainerror("input", constraints::positive(), -1.0);
169    //     let msg = with_suggestion(&error, "use absolute value or check input data");
170    //     assert!(msg.contains("input must be must be positive (> 0) (got: -1)"));
171    //     assert!(msg.contains("Suggestion: use absolute value or check input data"));
172    // }
173
174    // #[test]
175    // fn test_convergence_failed() {
176    //     let msg = convergence_failed("Newton-Raphson", 100, 1e-6);
177    //     assert_eq!(
178    //         msg,
179    //         "Newton-Raphson: failed to converge after 100 iterations (tolerance: 0.000001)"
180    //     );
181    // }
182}