Skip to main content

spectrafit_levenberg_marquardt/
error.rs

1//! Error variants for the Levenberg–Marquardt step computation.
2//!
3//! Mirrors the workspace convention established by `spectrafit-types`,
4//! `spectrafit-graph`, and `spectrafit-solver`: a crate that owns an error type
5//! declares it as a `thiserror` enum in its own `error.rs`, so the type
6//! implements `Display` and `std::error::Error` and can be `?`-converted by
7//! callers instead of only matched structurally.
8
9use thiserror::Error;
10
11/// Why a step could not be computed for the current `λ`.
12#[derive(Debug, Clone, Error)]
13pub enum StepError {
14    /// `(JᵀJ + λD²)` was not positive-definite — caller should raise `λ`.
15    #[error("(JᵀJ + λD²) was not positive-definite — raise λ and retry")]
16    NotPositiveDefinite,
17    /// A dense factorization (SVD) failed.
18    #[error("dense factorization (SVD) failed: {0}")]
19    Factorization(String),
20}
21
22#[cfg(test)]
23mod tests {
24    use super::*;
25    use std::error::Error;
26
27    fn assert_is_error<E: Error + 'static>() {}
28
29    #[test]
30    fn step_error_implements_std_error() {
31        assert_is_error::<StepError>();
32    }
33
34    #[test]
35    fn not_positive_definite_display_renders() {
36        let err = StepError::NotPositiveDefinite;
37        assert_eq!(
38            format!("{err}"),
39            "(JᵀJ + λD²) was not positive-definite — raise λ and retry"
40        );
41    }
42
43    #[test]
44    fn factorization_display_renders_with_payload() {
45        let err = StepError::Factorization("rank-deficient thin SVD".to_string());
46        assert_eq!(
47            format!("{err}"),
48            "dense factorization (SVD) failed: rank-deficient thin SVD"
49        );
50    }
51}