use crate::value::Value;
#[derive(Debug, Clone, PartialEq)]
pub enum Constraint {
Empty,
Universal,
Equals(Value),
Range {
min: Option<Value>,
max: Option<Value>,
},
}
impl Constraint {
pub fn is_satisfied_by(&self, value: &Value) -> bool {
match self {
Constraint::Equals(expected) => value == expected,
Constraint::Range { min, max } => {
if let Some(min_val) = min {
if !value.gte(min_val) {
return false;
}
}
if let Some(max_val) = max {
if !value.lte(max_val) {
return false;
}
}
true
}
Constraint::Empty => false,
Constraint::Universal => true,
}
}
pub fn map<F, E>(&self, f: F) -> Result<Constraint, E>
where
F: Fn(&Value) -> Result<Value, E>,
{
match self {
Constraint::Empty => Ok(Constraint::Empty),
Constraint::Universal => Ok(Constraint::Universal),
Constraint::Equals(v) => Ok(Constraint::Equals(f(v)?)),
Constraint::Range { min, max } => {
let new_min = min.as_ref().map(&f).transpose()?;
let new_max = max.as_ref().map(&f).transpose()?;
Ok(Constraint::Range {
min: new_min,
max: new_max,
})
}
}
}
}