use super::Domain;
use std::fmt::{Debug, Display, Formatter};
pub trait QuantitativeLimit = Copy + Display + Debug + PartialOrd;
#[derive(Debug, PartialEq, Hash, Eq, Clone)]
pub struct Quantitative<T: QuantitativeLimit> {
inf: T,
sup: T,
}
pub static NORMALIZATION_DOMAIN: Quantitative<f64> = Quantitative { inf: 0.0, sup: 1.0 };
#[derive(Debug, PartialEq)]
pub enum QuantitativeError<T: QuantitativeLimit> {
InvalidRange { inf: T, sup: T },
}
impl<T: QuantitativeLimit + Display> Display for QuantitativeError<T> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
use QuantitativeError::*;
match &self {
InvalidRange { inf, sup } => {
write!(f, "Inf ({}) > Sup ({}).", inf, sup)
}
}
}
}
impl<T: QuantitativeLimit> Domain for Quantitative<T> {}
impl<T: QuantitativeLimit + Copy> Quantitative<T> {
pub fn new(inf: T, sup: T) -> Result<Self, QuantitativeError<T>> {
use QuantitativeError::*;
if inf > sup {
Err(InvalidRange { inf, sup })
} else {
Ok(Self { inf, sup })
}
}
pub fn inf(&self) -> T {
self.inf
}
pub fn sup(&self) -> T {
self.sup
}
pub fn valid_assessment(&self, value: T) -> bool {
value >= self.inf && value <= self.sup
}
pub fn intersection(&self, other: &Self) -> Option<Self> {
if self.inf == self.sup || other.inf == other.sup {
None
} else if self.inf >= other.inf {
if self.sup <= other.sup {
Some(self.clone())
} else if self.inf < other.sup {
Some(Quantitative::new(self.inf, other.sup).unwrap())
} else {
None
}
} else if self.sup > other.inf {
if self.sup >= other.sup {
Some(other.clone())
} else {
Some(Quantitative::new(other.inf, self.sup).unwrap())
}
} else {
None
}
}
pub fn difference(&self, other: &Self) -> Vec<Self> {
let mut result = Vec::new();
if self.inf >= other.inf {
if self.inf >= other.sup {
result.push(self.clone());
} else if self.sup > other.sup {
result.push(Quantitative::new(other.sup, self.sup).unwrap());
}
} else if self.sup > other.inf {
if self.sup >= other.sup {
result.push(Quantitative::new(self.inf, other.inf).unwrap());
if self.sup > other.sup {
result.push(Quantitative::new(other.sup, self.sup).unwrap());
}
} else {
result.push(Quantitative::new(self.inf, other.inf).unwrap());
}
} else {
result.push(self.clone());
}
result
}
}