1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//! Error types for the autoeq crate.
//!
//! This module provides a unified error type for all autoeq operations,
//! following Microsoft Rust Guidelines for proper error handling.
use thiserror::Error;
/// Error type for autoeq operations.
///
/// This enum captures all possible errors that can occur during EQ optimization,
/// data loading, and result output operations.
#[derive(Debug, Error)]
pub enum AutoeqError {
/// A required CEA2034 curve is missing from the spin data.
#[error("missing CEA2034 curve: '{curve_name}'")]
MissingCea2034Curve {
/// Name of the missing curve (e.g., "On Axis", "Listening Window").
curve_name: String,
},
/// CEA2034 curves have inconsistent lengths.
#[error("CEA2034 curve length mismatch: on={on_len}, lw={lw_len}, sp={sp_len}, pir={pir_len}")]
CurveLengthMismatch {
/// Length of the On Axis curve.
on_len: usize,
/// Length of the Listening Window curve.
lw_len: usize,
/// Length of the Sound Power curve.
sp_len: usize,
/// Length of the Predicted In-Room curve.
pir_len: usize,
},
/// Failed to load a target curve from a file.
#[error("failed to load target curve from '{path}': {message}")]
TargetCurveLoad {
/// Path to the target curve file.
path: String,
/// Error message describing the failure.
message: String,
},
/// An invalid algorithm name was provided.
#[error("invalid algorithm name: '{name}'")]
InvalidAlgorithm {
/// The invalid algorithm name.
name: String,
},
/// A file operation failed (create, write, read).
#[error("file operation failed for '{path}': {message}")]
FileOperation {
/// Path to the file.
path: String,
/// Error message describing the failure.
message: String,
},
/// Directory creation failed.
#[error("failed to create directory '{path}': {message}")]
DirectoryCreation {
/// Path to the directory.
path: String,
/// Error message describing the failure.
message: String,
},
/// Optimization algorithm failed.
#[error("optimization failed: {message}")]
OptimizationFailed {
/// Error message describing the failure.
message: String,
},
/// Invalid measurement data.
#[error("invalid measurement: {message}")]
InvalidMeasurement {
/// Error message describing the issue.
message: String,
},
/// Invalid configuration.
#[error("invalid configuration: {message}")]
InvalidConfiguration {
/// Error message describing the issue.
message: String,
},
/// NLopt-specific error.
#[cfg(feature = "nlopt")]
#[error("NLopt error: {message}")]
NloptError {
/// Error message from NLopt.
message: String,
},
/// I/O error wrapper.
#[error("I/O error: {0}")]
Io(#[from] std::io::Error),
/// JSON serialization/deserialization error.
#[error("JSON error: {0}")]
Json(#[from] serde_json::Error),
}
/// Result type alias for autoeq operations.
pub type Result<T> = std::result::Result<T, AutoeqError>;
impl AutoeqError {
/// Returns true if this is a CEA2034 data error.
pub fn is_cea2034_error(&self) -> bool {
matches!(
self,
AutoeqError::MissingCea2034Curve { .. } | AutoeqError::CurveLengthMismatch { .. }
)
}
/// Returns true if this is a file/IO error.
pub fn is_io_error(&self) -> bool {
matches!(
self,
AutoeqError::FileOperation { .. }
| AutoeqError::DirectoryCreation { .. }
| AutoeqError::TargetCurveLoad { .. }
| AutoeqError::Io(_)
)
}
/// Returns true if this is an optimization error.
pub fn is_optimization_error(&self) -> bool {
#[cfg(feature = "nlopt")]
if matches!(self, AutoeqError::NloptError { .. }) {
return true;
}
matches!(self, AutoeqError::OptimizationFailed { .. })
}
}