use crate::ValidationError;
use core::convert::TryFrom;
use core::ops::{Deref, DerefMut, Index, IndexMut};
use nalgebra::DVector;
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum CriterionType {
Cost,
Profit,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct CriteriaTypes(DVector<CriterionType>);
impl TryFrom<i8> for CriterionType {
type Error = ValidationError;
fn try_from(value: i8) -> Result<Self, Self::Error> {
match value {
-1 => Ok(CriterionType::Cost),
1 => Ok(CriterionType::Profit),
_ => Err(ValidationError::InvalidValue),
}
}
}
impl CriteriaTypes {
pub fn new(values: &[CriterionType]) -> Self {
CriteriaTypes(DVector::from_vec(values.to_vec()))
}
pub fn from_slice(values: &[i8]) -> Result<Self, ValidationError> {
let mut criteria = DVector::from_element(values.len(), CriterionType::Cost);
for (i, &v) in values.iter().enumerate() {
criteria[i] = CriterionType::try_from(v)?;
}
Ok(CriteriaTypes(criteria))
}
pub fn len(&self) -> usize {
self.0.len()
}
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
pub fn all_profits(len: usize) -> Self {
CriteriaTypes(DVector::from_element(len, CriterionType::Profit))
}
pub fn all_costs(len: usize) -> Self {
CriteriaTypes(DVector::from_element(len, CriterionType::Cost))
}
pub fn invert_types(criteria_types: &CriteriaTypes) -> Self {
CriteriaTypes(criteria_types.map(|t| match t {
CriterionType::Cost => CriterionType::Profit,
CriterionType::Profit => CriterionType::Cost,
}))
}
}
impl Deref for CriteriaTypes {
type Target = DVector<CriterionType>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for CriteriaTypes {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl Index<usize> for CriteriaTypes {
type Output = CriterionType;
fn index(&self, index: usize) -> &Self::Output {
&self.0[index]
}
}
impl IndexMut<usize> for CriteriaTypes {
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
&mut self.0[index]
}
}
impl TryFrom<&[i8]> for CriteriaTypes {
type Error = ValidationError;
fn try_from(slice: &[i8]) -> Result<Self, Self::Error> {
CriteriaTypes::from_slice(slice)
}
}