resopt 0.3.0

Declarative constrained residual optimization in Rust
Documentation
use crate::solve::{Solution, SolveDiagnostics, SolveStatus};

/// Full outcome of a solve attempt.
#[derive(Debug, Clone, PartialEq)]
pub struct SolveResult {
    status: SolveStatus,
    solution: Option<Solution>,
    objective_value: Option<f64>,
    diagnostics: SolveDiagnostics,
}

impl SolveResult {
    pub fn new(
        status: SolveStatus,
        solution: Option<Solution>,
        objective_value: Option<f64>,
        diagnostics: SolveDiagnostics,
    ) -> Self {
        Self {
            status,
            solution,
            objective_value,
            diagnostics,
        }
    }

    pub fn status(&self) -> SolveStatus {
        self.status
    }

    pub fn solution(&self) -> Option<&Solution> {
        self.solution.as_ref()
    }

    pub fn objective_value(&self) -> Option<f64> {
        self.objective_value
    }

    pub fn diagnostics(&self) -> &SolveDiagnostics {
        &self.diagnostics
    }

    pub fn is_solved(&self) -> bool {
        self.status == SolveStatus::Solved
    }
}

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

    fn make_diag(reason: &str) -> SolveDiagnostics {
        SolveDiagnostics::new(0, reason.into(), 0.0, None)
    }

    #[test]
    fn solved() {
        let sol = Solution::new(vec![1.0, 2.0], None);
        let r = SolveResult::new(SolveStatus::Solved, Some(sol), Some(0.5), make_diag("ok"));
        assert!(r.is_solved());
        assert_eq!(r.status(), SolveStatus::Solved);
        assert!(r.solution().is_some());
        assert!((r.objective_value().unwrap() - 0.5).abs() < f64::EPSILON);
    }

    #[test]
    fn not_solved() {
        let r = SolveResult::new(SolveStatus::Infeasible, None, None, make_diag("fail"));
        assert!(!r.is_solved());
        assert!(r.solution().is_none());
        assert!(r.objective_value().is_none());
    }

    #[test]
    fn clone_and_eq() {
        let a = SolveResult::new(SolveStatus::NotImplemented, None, None, make_diag("x"));
        assert_eq!(a, a.clone());
    }
}