use std::fmt;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum MinuetError {
#[error("Memory at capacity: SNR {snr:.3} below threshold {threshold:.3}")]
AtCapacity {
snr: f64,
threshold: f64,
},
#[error("Capacity exceeded: store cannot accept more items")]
CapacityExceeded,
#[error("Cannot compute inverse: {message}")]
SingularInverse {
message: String,
},
#[error("Normalization failed: {message}")]
NormalizationFailed {
message: String,
},
#[error("Dimension mismatch: expected {expected}, got {actual}")]
DimensionMismatch {
expected: usize,
actual: usize,
},
#[error("Resonator failed to converge after {iterations} iterations (similarity: {final_similarity:.3})")]
ResonatorDidNotConverge {
iterations: usize,
final_similarity: f64,
},
#[error("Symbol not found in codebook: {0}")]
SymbolNotFound(String),
#[error("Codebook invariant violated: {0}")]
CodebookInvariant(String),
#[error("Configuration error: {0}")]
Configuration(String),
#[error("Persistence error: {0}")]
Persistence(#[from] std::io::Error),
#[cfg(feature = "serde")]
#[error("Serialization error: {0}")]
Serialization(#[from] bincode::Error),
#[error("Invalid query: {0}")]
InvalidQuery(String),
#[error("Invalid temperature beta={beta}: must be in range ({min}, {max})")]
InvalidTemperature {
beta: f64,
min: f64,
max: f64,
},
#[error("Algebraic constraint violated: {constraint} (value: {value:.6})")]
AlgebraicConstraint {
constraint: String,
value: f64,
},
#[error("Invalid grade {grade} for dimension {dim}")]
InvalidGrade {
grade: usize,
dim: usize,
},
#[error("Merge failed: {0}")]
MergeFailed(String),
#[cfg(feature = "persistence")]
#[error("Recovery failed: {0}")]
RecoveryFailed(String),
#[error("Not implemented: {feature}")]
NotImplemented {
feature: String,
},
#[error("Algebra error: {0}")]
Algebra(String),
}
pub type MinuetResult<T> = std::result::Result<T, MinuetError>;
pub type Result<T> = MinuetResult<T>;
impl MinuetError {
pub fn algebra(msg: impl fmt::Display) -> Self {
Self::Algebra(msg.to_string())
}
pub fn config(msg: impl Into<String>) -> Self {
Self::Configuration(msg.into())
}
pub fn not_implemented(feature: impl Into<String>) -> Self {
Self::NotImplemented {
feature: feature.into(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn error_display_formatting() {
let err = MinuetError::AtCapacity {
snr: 0.123,
threshold: 0.5,
};
assert!(err.to_string().contains("0.123"));
assert!(err.to_string().contains("0.500"));
}
#[test]
fn algebra_error_from_string() {
let err = MinuetError::algebra("test error");
assert!(err.to_string().contains("test error"));
}
}