resopt 0.3.0

Declarative constrained residual optimization in Rust
Documentation
use std::fmt;

/// Public error type for the crate.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Error {
    InvalidMatrixShape { expected: usize, got: usize },
    DimensionMismatch { message: String },
    InvalidParameter { message: String },
    MissingField { field: &'static str },
    SolverFailure { message: String },
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Self::InvalidMatrixShape { expected, got } => {
                write!(
                    f,
                    "invalid matrix shape: expected {} coefficients, got {}",
                    expected, got
                )
            }
            Self::DimensionMismatch { message } => {
                write!(f, "dimension mismatch: {}", message)
            }
            Self::InvalidParameter { message } => {
                write!(f, "invalid parameter: {}", message)
            }
            Self::MissingField { field } => {
                write!(f, "missing required field: {}", field)
            }
            Self::SolverFailure { message } => {
                write!(f, "solver failure: {}", message)
            }
        }
    }
}

impl std::error::Error for Error {}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn display_invalid_matrix_shape() {
        let e = Error::InvalidMatrixShape {
            expected: 6,
            got: 4,
        };
        let msg = format!("{}", e);
        assert!(msg.contains("6") && msg.contains("4"));
    }

    #[test]
    fn display_dimension_mismatch() {
        let e = Error::DimensionMismatch {
            message: "test dim".into(),
        };
        assert!(format!("{}", e).contains("test dim"));
    }

    #[test]
    fn display_invalid_parameter() {
        let e = Error::InvalidParameter {
            message: "bad param".into(),
        };
        assert!(format!("{}", e).contains("bad param"));
    }

    #[test]
    fn display_missing_field() {
        let e = Error::MissingField { field: "loss" };
        assert!(format!("{}", e).contains("loss"));
    }

    #[test]
    fn display_solver_failure() {
        let e = Error::SolverFailure {
            message: "boom".into(),
        };
        assert!(format!("{}", e).contains("boom"));
    }

    #[test]
    fn is_std_error() {
        let e: Box<dyn std::error::Error> = Box::new(Error::SolverFailure {
            message: "test".into(),
        });
        assert!(format!("{}", e).contains("test"));
    }
}