use thiserror::Error;
pub type QuantResult<T> = Result<T, QuantError>;
#[derive(Debug, Error, Clone, PartialEq)]
pub enum QuantError {
#[error("dimension mismatch: expected {expected}, got {got}")]
DimensionMismatch { expected: usize, got: usize },
#[error("empty input: {0}")]
EmptyInput(&'static str),
#[error("invalid scale {scale}: must be finite and positive")]
InvalidScale { scale: f32 },
#[error("invalid bit-width {bits}: must be in [1, 16]")]
InvalidBitWidth { bits: u32 },
#[error("tensor length {len} is not divisible by group size {group}")]
GroupSizeMismatch { len: usize, group: usize },
#[error("calibration data required for {0}")]
CalibrationRequired(&'static str),
#[error("Hessian is near-singular (min diagonal = {min_diag:.3e})")]
SingularHessian { min_diag: f32 },
#[error("teacher output length {teacher} != student output length {student}")]
TeacherStudentMismatch { teacher: usize, student: usize },
#[error("pruning threshold {threshold:.4} zeroed all {n} weights")]
AllZeroPruning { threshold: f32, n: usize },
#[error("FP8 encoding received non-finite value {0}")]
NonFiniteFp8(f32),
#[error("cannot achieve target ratio {target:.2}× with given sensitivity")]
InfeasibleCompressionTarget { target: f32 },
#[error("invalid configuration: {0}")]
InvalidConfig(String),
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn error_display_dimension_mismatch() {
let e = QuantError::DimensionMismatch {
expected: 4,
got: 3,
};
assert!(e.to_string().contains("dimension mismatch"));
}
#[test]
fn error_display_invalid_scale() {
let e = QuantError::InvalidScale { scale: -0.5 };
assert!(e.to_string().contains("invalid scale"));
}
#[test]
fn error_display_group_size() {
let e = QuantError::GroupSizeMismatch { len: 10, group: 3 };
assert!(e.to_string().contains("not divisible"));
}
#[test]
fn result_alias_ok() {
let r: QuantResult<i32> = Ok(42);
assert!(r.is_ok());
}
}