fn compare()

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))
        }
    }
}