use thiserror::Error;
#[derive(Error, Debug, Clone, PartialEq)]
pub enum SparseError {
#[error("indices must be sorted in ascending order")]
UnsortedIndices,
#[error("duplicate index at position {0}")]
DuplicateIndex(usize),
#[error("index {index} exceeds dimension {dim}")]
IndexOutOfBounds {
index: u32,
dim: u32,
},
#[error("value at index {0} is NaN or Infinity")]
InvalidValue(usize),
#[error("sparse vector must have at least one element")]
EmptyVector,
#[error("indices and values length mismatch: {indices} vs {values}")]
LengthMismatch {
indices: usize,
values: usize,
},
#[error("sparse ID {0} not found")]
IdNotFound(u64),
#[error("cannot normalize zero vector")]
ZeroNorm,
#[error("IO error: {0}")]
Io(String),
#[error("invalid magic number: expected {expected:?}, found {found:?}")]
InvalidMagic {
expected: [u8; 4],
found: [u8; 4],
},
#[error("unsupported format version: expected {expected}, found {found}")]
UnsupportedVersion {
expected: u32,
found: u32,
},
#[error("corrupted data: {0}")]
CorruptedData(String),
#[error("ID counter overflow: cannot assign more IDs (u64::MAX reached)")]
IdOverflow,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_error_display_unsorted() {
let err = SparseError::UnsortedIndices;
assert!(err.to_string().contains("sorted"));
}
#[test]
fn test_error_display_duplicate() {
let err = SparseError::DuplicateIndex(5);
assert!(err.to_string().contains('5'));
}
#[test]
fn test_error_display_out_of_bounds() {
let err = SparseError::IndexOutOfBounds {
index: 100,
dim: 50,
};
assert!(err.to_string().contains("100"));
assert!(err.to_string().contains("50"));
}
#[test]
fn test_error_display_invalid_value() {
let err = SparseError::InvalidValue(3);
assert!(err.to_string().contains('3'));
}
#[test]
fn test_error_display_empty() {
let err = SparseError::EmptyVector;
assert!(err.to_string().contains("at least one"));
}
#[test]
fn test_error_display_length_mismatch() {
let err = SparseError::LengthMismatch {
indices: 5,
values: 3,
};
assert!(err.to_string().contains('5'));
assert!(err.to_string().contains('3'));
}
#[test]
fn test_error_display_id_not_found() {
let err = SparseError::IdNotFound(42);
assert!(err.to_string().contains("42"));
}
#[test]
fn test_error_display_zero_norm() {
let err = SparseError::ZeroNorm;
assert!(err.to_string().contains("zero"));
}
#[test]
fn test_error_display_id_overflow() {
let err = SparseError::IdOverflow;
assert!(err.to_string().contains("overflow"));
}
}