use std::convert::TryFrom;
use std::fmt::{Debug, Formatter};
use std::num::TryFromIntError;
use std::os::raw::c_int;
use highs_sys::*;
#[derive(Clone, Copy, Debug, PartialOrd, PartialEq, Ord, Eq)]
#[non_exhaustive]
pub enum HighsModelStatus {
NotSet = MODEL_STATUS_NOTSET as isize,
LoadError = MODEL_STATUS_LOAD_ERROR as isize,
ModelError = MODEL_STATUS_MODEL_ERROR as isize,
PresolveError = MODEL_STATUS_PRESOLVE_ERROR as isize,
SolveError = MODEL_STATUS_SOLVE_ERROR as isize,
PostsolveError = MODEL_STATUS_POSTSOLVE_ERROR as isize,
ModelEmpty = MODEL_STATUS_MODEL_EMPTY as isize,
Infeasible = MODEL_STATUS_INFEASIBLE as isize,
UnboundedOrInfeasible = MODEL_STATUS_UNBOUNDED_OR_INFEASIBLE as isize,
Unbounded = MODEL_STATUS_UNBOUNDED as isize,
Optimal = MODEL_STATUS_OPTIMAL as isize,
ObjectiveBound = MODEL_STATUS_OBJECTIVE_BOUND as isize,
ObjectiveTarget = MODEL_STATUS_OBJECTIVE_TARGET as isize,
ReachedTimeLimit = MODEL_STATUS_REACHED_TIME_LIMIT as isize,
ReachedIterationLimit = MODEL_STATUS_REACHED_ITERATION_LIMIT as isize,
Unknown = MODEL_STATUS_UNKNOWN as isize,
ReachedSolutionLimit = MODEL_STATUS_REACHED_SOLUTION_LIMIT as isize,
ReachedInterrupt = MODEL_STATUS_REACHED_INTERRUPT as isize,
ReachedMemoryLimit = MODEL_STATUS_REACHED_MEMORY_LIMIT as isize,
}
#[derive(PartialEq, Clone, Copy)]
pub struct InvalidStatus(pub c_int);
impl Debug for InvalidStatus {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{} is not a valid HiGHS model status. \
This error comes from a bug in highs rust bindings. \
Please report it.",
self.0
)
}
}
impl TryFrom<c_int> for HighsModelStatus {
type Error = InvalidStatus;
fn try_from(value: c_int) -> Result<Self, Self::Error> {
match value {
MODEL_STATUS_NOTSET => Ok(Self::NotSet),
MODEL_STATUS_LOAD_ERROR => Ok(Self::LoadError),
MODEL_STATUS_MODEL_ERROR => Ok(Self::ModelError),
MODEL_STATUS_PRESOLVE_ERROR => Ok(Self::PresolveError),
MODEL_STATUS_SOLVE_ERROR => Ok(Self::SolveError),
MODEL_STATUS_POSTSOLVE_ERROR => Ok(Self::PostsolveError),
MODEL_STATUS_MODEL_EMPTY => Ok(Self::ModelEmpty),
MODEL_STATUS_INFEASIBLE => Ok(Self::Infeasible),
MODEL_STATUS_UNBOUNDED => Ok(Self::Unbounded),
MODEL_STATUS_UNBOUNDED_OR_INFEASIBLE => Ok(Self::UnboundedOrInfeasible),
MODEL_STATUS_OPTIMAL => Ok(Self::Optimal),
MODEL_STATUS_OBJECTIVE_BOUND => Ok(Self::ObjectiveBound),
MODEL_STATUS_OBJECTIVE_TARGET => Ok(Self::ObjectiveTarget),
MODEL_STATUS_REACHED_TIME_LIMIT => Ok(Self::ReachedTimeLimit),
MODEL_STATUS_REACHED_ITERATION_LIMIT => Ok(Self::ReachedIterationLimit),
MODEL_STATUS_UNKNOWN => Ok(Self::Unknown),
MODEL_STATUS_REACHED_SOLUTION_LIMIT => Ok(Self::ReachedSolutionLimit),
MODEL_STATUS_REACHED_INTERRUPT => Ok(Self::ReachedInterrupt),
MODEL_STATUS_REACHED_MEMORY_LIMIT => Ok(Self::ReachedMemoryLimit),
n => Err(InvalidStatus(n)),
}
}
}
#[derive(Clone, Copy, Debug, PartialOrd, PartialEq, Ord, Eq)]
pub enum HighsStatus {
OK = 0,
Warning = 1,
Error = 2,
}
impl From<TryFromIntError> for HighsStatus {
fn from(_: TryFromIntError) -> Self {
Self::Error
}
}
impl TryFrom<c_int> for HighsStatus {
type Error = InvalidStatus;
fn try_from(value: c_int) -> Result<Self, InvalidStatus> {
match value {
STATUS_OK => Ok(Self::OK),
STATUS_WARNING => Ok(Self::Warning),
STATUS_ERROR => Ok(Self::Error),
n => Err(InvalidStatus(n)),
}
}
}
#[derive(Clone, Copy, Debug, PartialOrd, PartialEq, Ord, Eq)]
pub enum HighsSolutionStatus {
None = SOLUTION_STATUS_NONE as isize,
Infeasible = SOLUTION_STATUS_INFEASIBLE as isize,
Feasible = SOLUTION_STATUS_FEASIBLE as isize,
}
impl TryFrom<c_int> for HighsSolutionStatus {
type Error = InvalidStatus;
fn try_from(value: c_int) -> Result<Self, Self::Error> {
match value {
SOLUTION_STATUS_NONE => Ok(Self::None),
SOLUTION_STATUS_INFEASIBLE => Ok(Self::Infeasible),
SOLUTION_STATUS_FEASIBLE => Ok(Self::Feasible),
n => Err(InvalidStatus(n)),
}
}
}