1use std::fmt;
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
25pub enum NamErrorCode {
26 FileNotFound,
29 FileReadError,
31 UnknownExtension,
33 NamJsonParseError,
35 NamJsonWeightsExceedLimit,
37 NamJsonTrainingTooLarge,
39 NamJsonTrainingTooDeep,
41 NamJsonSubmodelsExceedLimit,
43 NamJsonSubmodelsTooDeep,
45 NamJsonWeightNotFinite,
47 NamJsonInvalidSampleRate,
49 NamJsonUnsupportedTopology,
51 NamJsonInvalidVersionFormat,
53 NamJsonUnsupportedVersion,
55 NamJsonUnsupportedMultiChannel,
57 NambNonFiniteWeight,
59 NambInvalidHeaderField,
61 NambCrc32Mismatch,
63 NambCrc32Missing,
65 NambInvalidMagic,
67 NambUnsupportedVersion,
69 NambTruncated,
71 UnsupportedArchitecture,
73 TopologyDetectionFailed,
75 WeightCountMismatch,
77 ModelBuildFailed,
79 ModelTooLarge,
81
82 PipewireInitFailed,
85 StreamConnectFailed,
87 ResamplerBuildFailed,
89 ResamplerChannelFull,
91 SchedFifoDenied,
93 CpuAffinityFailed,
95 DeadlineExceeded,
97
98 ParamChannelFull,
101
102 InvalidGainValue,
105 UnknownCommand,
107 CtrlCHandlerFailed,
109 IrLoadFailed,
111 GcOverflow,
113 GcCorrupted,
115 OutOfMemory,
117}
118
119impl NamErrorCode {
120 pub fn code(self) -> &'static str {
122 match self {
123 Self::FileNotFound => "E1100",
124 Self::FileReadError => "E1101",
125 Self::UnknownExtension => "E1102",
126 Self::NamJsonParseError => "E1200",
127 Self::NamJsonWeightsExceedLimit => "E1206",
128 Self::NamJsonTrainingTooLarge => "E1207",
129 Self::NamJsonTrainingTooDeep => "E1208",
130 Self::NamJsonSubmodelsExceedLimit => "E1209",
131 Self::NamJsonSubmodelsTooDeep => "E1210",
132 Self::NamJsonWeightNotFinite => "E1211",
133 Self::NamJsonInvalidSampleRate => "E1214",
134 Self::NamJsonUnsupportedTopology => "E1215",
135 Self::NamJsonInvalidVersionFormat => "E1216",
136 Self::NamJsonUnsupportedVersion => "E1217",
137 Self::NamJsonUnsupportedMultiChannel => "E1218",
138 Self::NambNonFiniteWeight => "E1212",
139 Self::NambInvalidHeaderField => "E1213",
140 Self::NambCrc32Mismatch => "E1201",
141 Self::NambCrc32Missing => "E1205",
142 Self::NambInvalidMagic => "E1202",
143 Self::NambUnsupportedVersion => "E1203",
144 Self::NambTruncated => "E1204",
145 Self::UnsupportedArchitecture => "E1300",
146 Self::TopologyDetectionFailed => "E1301",
147 Self::WeightCountMismatch => "E1302",
148 Self::ModelBuildFailed => "E1303",
149 Self::ModelTooLarge => "E1304",
150 Self::PipewireInitFailed => "E2100",
151 Self::StreamConnectFailed => "E2101",
152 Self::ResamplerBuildFailed => "E2200",
153 Self::ResamplerChannelFull => "E2201",
154 Self::SchedFifoDenied => "E2300",
155 Self::CpuAffinityFailed => "E2301",
156 Self::DeadlineExceeded => "E2001",
157 Self::ParamChannelFull => "E3100",
158 Self::GcOverflow => "E3101",
159 Self::GcCorrupted => "E3102",
160 Self::InvalidGainValue => "E4100",
161 Self::UnknownCommand => "E4101",
162 Self::CtrlCHandlerFailed => "E4102",
163 Self::IrLoadFailed => "E4103",
164 Self::OutOfMemory => "E5000",
165 }
166 }
167
168 pub fn message(self) -> &'static str {
170 match self {
171 Self::FileNotFound => "File not found",
172 Self::FileReadError => "File read error",
173 Self::UnknownExtension => "Unknown extension",
174 Self::NamJsonParseError => "Invalid JSON format",
175 Self::NamJsonWeightsExceedLimit => "JSON weights exceed limit",
176 Self::NamJsonTrainingTooLarge => "Training metadata too large",
177 Self::NamJsonTrainingTooDeep => "Training metadata too deeply nested",
178 Self::NamJsonSubmodelsExceedLimit => "Submodels count exceeds limit (max 8)",
179 Self::NamJsonSubmodelsTooDeep => "Container nesting too deep",
180 Self::NamJsonWeightNotFinite => "JSON weight is non-finite (NaN/Inf)",
181 Self::NamJsonInvalidSampleRate => {
182 "JSON sample_rate is invalid (must be finite and > 0)"
183 }
184 Self::NamJsonUnsupportedTopology => {
185 "JSON topology exceeds OOM safety limits (MAX_LAYERS or MAX_HIDDEN_SIZE)"
186 }
187 Self::NamJsonInvalidVersionFormat => "JSON version string is not parseable as SemVer",
188 Self::NamJsonUnsupportedVersion => {
189 "JSON version is outside the supported range (min 0.5.0, max 0.7.x)"
190 }
191 Self::NamJsonUnsupportedMultiChannel => {
192 "LSTM model has multi-channel I/O (only mono supported)"
193 }
194 Self::NambNonFiniteWeight => "NAMB weight is non-finite (NaN/Inf)",
195 Self::NambInvalidHeaderField => "NAMB header field is invalid",
196 Self::NambCrc32Mismatch => "CRC32 checksum mismatch",
197 Self::NambCrc32Missing => "CRC32 integrity flag missing (v2+)",
198 Self::NambInvalidMagic => "Invalid signature",
199 Self::NambUnsupportedVersion => "Unsupported version",
200 Self::NambTruncated => "Corrupted/truncated file",
201 Self::UnsupportedArchitecture => "Unsupported architecture",
202 Self::TopologyDetectionFailed => "Topology detection failed",
203 Self::WeightCountMismatch => "Weight count mismatch",
204 Self::ModelBuildFailed => "Model build failed",
205 Self::ModelTooLarge => "Model file too large",
206 Self::PipewireInitFailed => "PipeWire initialization failed",
207 Self::StreamConnectFailed => "Stream connection failed",
208 Self::ResamplerBuildFailed => "Resampler build failed",
209 Self::ResamplerChannelFull => "Resampler channel full",
210 Self::SchedFifoDenied => "SCHED_FIFO denied",
211 Self::CpuAffinityFailed => "CPU affinity setting failed",
212 Self::DeadlineExceeded => "Processing deadline exceeded",
213 Self::ParamChannelFull => "Parameter channel full",
214 Self::GcOverflow => "Garbage collection overflow",
215 Self::GcCorrupted => "Garbage collection corruption",
216 Self::InvalidGainValue => "Invalid gain value",
217 Self::UnknownCommand => "Unknown command",
218 Self::CtrlCHandlerFailed => "Ctrl-C handler setup failed",
219 Self::IrLoadFailed => "Cab-sim IR load failed",
220 Self::OutOfMemory => "Out of memory",
221 }
222 }
223
224 pub fn mnemonic(self) -> &'static str {
226 match self {
227 Self::FileNotFound => "FILE_NOT_FOUND",
228 Self::FileReadError => "FILE_READ_ERROR",
229 Self::UnknownExtension => "UNKNOWN_EXTENSION",
230 Self::NamJsonParseError => "NAM_JSON_PARSE_ERROR",
231 Self::NamJsonWeightsExceedLimit => "NAM_JSON_WEIGHTS_EXCEED_LIMIT",
232 Self::NamJsonTrainingTooLarge => "NAM_JSON_TRAINING_TOO_LARGE",
233 Self::NamJsonTrainingTooDeep => "NAM_JSON_TRAINING_TOO_DEEP",
234 Self::NamJsonSubmodelsExceedLimit => "NAM_JSON_SUBMODELS_EXCEED_LIMIT",
235 Self::NamJsonSubmodelsTooDeep => "NAM_JSON_SUBMODELS_TOO_DEEP",
236 Self::NamJsonWeightNotFinite => "NAM_JSON_WEIGHT_NOT_FINITE",
237 Self::NamJsonInvalidSampleRate => "NAM_JSON_INVALID_SAMPLE_RATE",
238 Self::NamJsonUnsupportedTopology => "NAM_JSON_UNSUPPORTED_TOPOLOGY",
239 Self::NamJsonInvalidVersionFormat => "NAM_JSON_INVALID_VERSION_FORMAT",
240 Self::NamJsonUnsupportedVersion => "NAM_JSON_UNSUPPORTED_VERSION",
241 Self::NamJsonUnsupportedMultiChannel => "NAM_JSON_UNSUPPORTED_MULTI_CHANNEL",
242 Self::NambNonFiniteWeight => "NAMB_NON_FINITE_WEIGHT",
243 Self::NambInvalidHeaderField => "NAMB_INVALID_HEADER_FIELD",
244 Self::NambCrc32Mismatch => "NAMB_CRC32_MISMATCH",
245 Self::NambCrc32Missing => "NAMB_CRC32_MISSING",
246 Self::NambInvalidMagic => "NAMB_INVALID_MAGIC",
247 Self::NambUnsupportedVersion => "NAMB_UNSUPPORTED_VERSION",
248 Self::NambTruncated => "NAMB_TRUNCATED",
249 Self::UnsupportedArchitecture => "UNSUPPORTED_ARCHITECTURE",
250 Self::TopologyDetectionFailed => "TOPOLOGY_DETECTION_FAILED",
251 Self::WeightCountMismatch => "WEIGHT_COUNT_MISMATCH",
252 Self::ModelBuildFailed => "MODEL_BUILD_FAILED",
253 Self::ModelTooLarge => "MODEL_TOO_LARGE",
254 Self::PipewireInitFailed => "PIPEWIRE_INIT_FAILED",
255 Self::StreamConnectFailed => "STREAM_CONNECT_FAILED",
256 Self::ResamplerBuildFailed => "RESAMPLER_BUILD_FAILED",
257 Self::ResamplerChannelFull => "RESAMPLER_CHANNEL_FULL",
258 Self::SchedFifoDenied => "SCHED_FIFO_DENIED",
259 Self::CpuAffinityFailed => "CPU_AFFINITY_FAILED",
260 Self::DeadlineExceeded => "DEADLINE_EXCEEDED",
261 Self::ParamChannelFull => "PARAM_CHANNEL_FULL",
262 Self::GcOverflow => "GC_OVERFLOW",
263 Self::GcCorrupted => "GC_CORRUPTED",
264 Self::InvalidGainValue => "INVALID_GAIN_VALUE",
265 Self::UnknownCommand => "UNKNOWN_COMMAND",
266 Self::CtrlCHandlerFailed => "CTRL_C_HANDLER_FAILED",
267 Self::IrLoadFailed => "IR_LOAD_FAILED",
268 Self::OutOfMemory => "OUT_OF_MEMORY",
269 }
270 }
271}
272
273impl std::error::Error for NamErrorCode {}
274
275impl fmt::Display for NamErrorCode {
276 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
277 write!(f, "{} | {}", self.code(), self.mnemonic())
278 }
279}