#[cfg(feature = "serde1")]
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Eq, PartialEq, Hash, Default)]
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
pub enum TerminationStatus {
Terminated(TerminationReason),
#[default]
NotTerminated,
}
impl TerminationStatus {
pub fn terminated(&self) -> bool {
matches!(self, TerminationStatus::Terminated(_))
}
}
impl std::fmt::Display for TerminationStatus {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
TerminationStatus::Terminated(reason) => f.write_str(reason.text()),
TerminationStatus::NotTerminated => f.write_str("Running"),
}
}
}
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
#[cfg_attr(feature = "serde1", derive(Serialize, Deserialize))]
pub enum TerminationReason {
MaxItersReached,
TargetCostReached,
Interrupt,
SolverConverged,
Timeout,
SolverExit(String),
}
impl TerminationReason {
pub fn text(&self) -> &str {
match self {
TerminationReason::MaxItersReached => "Maximum number of iterations reached",
TerminationReason::TargetCostReached => "Target cost value reached",
TerminationReason::Interrupt => "Interrupt",
TerminationReason::SolverConverged => "Solver converged",
TerminationReason::Timeout => "Timeout reached",
TerminationReason::SolverExit(reason) => reason.as_ref(),
}
}
}
impl std::fmt::Display for TerminationReason {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.text())
}
}
impl Default for TerminationReason {
fn default() -> Self {
TerminationReason::SolverExit("Undefined".to_string())
}
}
#[cfg(test)]
mod tests {
use super::*;
send_sync_test!(termination_reason, TerminationReason);
}