use indexmap::IndexSet;
use crate::util::{EvaluationError, EvaluationUtils, EvaluationValue, Validate};
#[derive(Clone, Copy, Debug, Default)]
pub struct Bools;
impl Bools {
#[must_use]
pub const fn new() -> Self {
Self
}
pub fn is_true(&self, target: &EvaluationValue) -> Result<bool, EvaluationError> {
EvaluationUtils::evaluate_as_boolean(target)
}
pub fn array_is_true(
&self,
target: Option<&[EvaluationValue]>,
) -> Result<Vec<bool>, EvaluationError> {
map_values(validate_target(target)?, |value| self.is_true(value))
}
pub fn list_is_true(
&self,
target: Option<&[EvaluationValue]>,
) -> Result<Vec<bool>, EvaluationError> {
map_values(validate_target(target)?, |value| self.is_true(value))
}
pub fn set_is_true(
&self,
target: Option<&[EvaluationValue]>,
) -> Result<IndexSet<bool>, EvaluationError> {
set_values(validate_target(target)?, |value| self.is_true(value))
}
pub fn is_false(&self, target: &EvaluationValue) -> Result<bool, EvaluationError> {
self.is_true(target).map(|value| !value)
}
pub fn array_is_false(
&self,
target: Option<&[EvaluationValue]>,
) -> Result<Vec<bool>, EvaluationError> {
map_values(validate_target(target)?, |value| self.is_false(value))
}
pub fn list_is_false(
&self,
target: Option<&[EvaluationValue]>,
) -> Result<Vec<bool>, EvaluationError> {
map_values(validate_target(target)?, |value| self.is_false(value))
}
pub fn set_is_false(
&self,
target: Option<&[EvaluationValue]>,
) -> Result<IndexSet<bool>, EvaluationError> {
set_values(validate_target(target)?, |value| self.is_false(value))
}
pub fn array_and(&self, target: Option<&[EvaluationValue]>) -> Result<bool, EvaluationError> {
and_values(validate_target(target)?)
}
pub fn list_and(&self, target: Option<&[EvaluationValue]>) -> Result<bool, EvaluationError> {
and_values(validate_target(target)?)
}
pub fn set_and(&self, target: Option<&[EvaluationValue]>) -> Result<bool, EvaluationError> {
and_values(validate_target(target)?)
}
pub fn array_or(&self, target: Option<&[EvaluationValue]>) -> Result<bool, EvaluationError> {
or_values(validate_target(target)?)
}
pub fn list_or(&self, target: Option<&[EvaluationValue]>) -> Result<bool, EvaluationError> {
or_values(validate_target(target)?)
}
pub fn set_or(&self, target: Option<&[EvaluationValue]>) -> Result<bool, EvaluationError> {
or_values(validate_target(target)?)
}
}
fn validate_target(
target: Option<&[EvaluationValue]>,
) -> Result<&[EvaluationValue], EvaluationError> {
Validate::not_null(target, Some("Target cannot be null"))?;
Ok(target.expect("validated non-null target"))
}
fn map_values(
target: &[EvaluationValue],
predicate: impl Fn(&EvaluationValue) -> Result<bool, EvaluationError>,
) -> Result<Vec<bool>, EvaluationError> {
target.iter().map(predicate).collect()
}
fn set_values(
target: &[EvaluationValue],
predicate: impl Fn(&EvaluationValue) -> Result<bool, EvaluationError>,
) -> Result<IndexSet<bool>, EvaluationError> {
target.iter().map(predicate).collect()
}
fn and_values(target: &[EvaluationValue]) -> Result<bool, EvaluationError> {
for value in target {
if !EvaluationUtils::evaluate_as_boolean(value)? {
return Ok(false);
}
}
Ok(true)
}
fn or_values(target: &[EvaluationValue]) -> Result<bool, EvaluationError> {
for value in target {
if EvaluationUtils::evaluate_as_boolean(value)? {
return Ok(true);
}
}
Ok(false)
}