use crate::imports::*;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct ValRange<T>(
T,
T,
);
impl<T> SerdeAPI for ValRange<T> where T: Serialize + for<'a> Deserialize<'a> {}
trait ValRangeCheck<T> {
fn in_range(&self, val: &T) -> bool;
fn constrain(&self, val: &T) -> T;
fn min_max(&mut self, val: &T);
}
impl<T> ValRangeCheck<T> for ValRange<T>
where
T: Ord + PartialEq + Clone,
{
fn in_range(&self, val: &T) -> bool {
(&self.0..=&self.1).contains(&val)
}
fn constrain(&self, val: &T) -> T {
cmp::min(self.1.clone(), cmp::max(self.0.clone(), val.clone()))
}
fn min_max(&mut self, val: &T) {
self.0 = cmp::min(self.0.clone(), val.clone());
self.1 = cmp::max(self.1.clone(), val.clone());
}
}
impl<T> ValRangeCheck<ValRange<T>> for ValRange<T>
where
T: Ord + PartialEq + Clone,
{
fn in_range(&self, range: &ValRange<T>) -> bool {
self.0 <= range.0 && range.1 <= self.1
}
fn constrain(&self, range: &ValRange<T>) -> ValRange<T> {
Self(
cmp::min(self.1.clone(), cmp::max(self.0.clone(), range.0.clone())),
cmp::min(self.1.clone(), cmp::max(self.0.clone(), range.1.clone())),
)
}
fn min_max(&mut self, other: &ValRange<T>) {
self.0 = cmp::min(self.0.clone(), other.0.clone());
self.1 = cmp::max(self.1.clone(), other.1.clone());
}
}
impl<T> ValRange<T>
where
T: PartialOrd + PartialEq + Sub + Clone,
{
pub fn is_single_val(&self) -> bool {
self.0 == self.1
}
pub fn diff(&self) -> <T as Sub>::Output {
self.1.clone() - self.0.clone()
}
pub fn validate(&self) {
assert!(self.0 < self.1)
}
}