use crate::solve::{Solution, SolveDiagnostics, SolveStatus};
#[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());
}
}