in guard/src/rules/evaluate.rs [191:255]
fn compare<F>(lhs: &Vec<&PathAwareValue>,
_lhs_query: &[QueryPart<'_>],
rhs: &Vec<&PathAwareValue>,
_rhs_query: Option<&[QueryPart<'_>]>,
compare: F,
any: bool, atleast_one: bool) -> Result<(Status, Vec<(bool, Option<PathAwareValue>, Option<PathAwareValue>)>)>
where F: Fn(&PathAwareValue, &PathAwareValue) -> Result<bool>
{
if lhs.is_empty() || rhs.is_empty() {
return Ok((Status::FAIL, vec![]))
}
let lhs = if is_mixed_values_results(lhs) {
merge_mixed_results(lhs)
} else {
lhs.to_vec()
};
let rhs = if is_mixed_values_results(rhs) {
merge_mixed_results(rhs)
} else {
rhs.to_vec()
};
let lhs_elem_has_list = lhs[0].is_list();
let rhs_elem_has_list = rhs[0].is_list();
//
// What are possible comparisons
//
if !lhs_elem_has_list && !rhs_elem_has_list {
match compare_loop(&lhs, &rhs, compare, any, atleast_one) {
Ok((true, outcomes)) => Ok((Status::PASS, outcomes)),
Ok((false, outcomes)) => Ok((Status::FAIL, outcomes)),
Err(e) => Err(e)
}
}
else if lhs_elem_has_list && !rhs_elem_has_list {
for elevated in elevate_inner(&lhs)? {
if let Ok((cmp, outcomes)) = compare_loop(
&elevated, &rhs, |f, s| compare(f, s), any, atleast_one) {
if !cmp {
return Ok((Status::FAIL, outcomes))
}
}
}
Ok((Status::PASS, vec![]))
}
else if (!lhs_elem_has_list || any) && rhs_elem_has_list {
for elevated in elevate_inner(&rhs)? {
if let Ok((cmp, outcomes)) = compare_loop(
&lhs, &elevated, |f, s| compare(f, s), any, atleast_one) {
if !cmp {
return Ok((Status::FAIL, outcomes))
}
}
}
Ok((Status::PASS, vec![]))
}
else {
match compare_loop(&lhs, &rhs, compare, any, atleast_one)? {
(true, _) => Ok((Status::PASS, vec![])),
(false, outcomes) => Ok((Status::FAIL, outcomes))
}
}
}