xfeval/calculate/functions/
logical.rs

1use super::super::calculator::calculate_formula;
2use super::super::operators::boolean::*;
3use super::super::utils::*;
4use crate::error::ValueError;
5use crate::value::{Boolean, Value};
6use crate::Expression;
7
8pub fn calculate_iff(iff_arguments: (Value, Value, Value)) -> Value {
9    let (false_value, true_value, bool_expression) = iff_arguments;
10    match bool_expression {
11        Value::Boolean(bool_value) => {
12            if to_bool(bool_value) {
13                true_value
14            } else {
15                false_value
16            }
17        }
18        Value::Number(number_value) => {
19            if number_value == 0.0 {
20                false_value
21            } else {
22                true_value
23            }
24        }
25        Value::Blank => false_value,
26        Value::Error(_) => bool_expression,
27        _ => Value::Error(crate::error::ValueError::Value),
28    }
29}
30
31pub fn calculate_isblank(value: Value) -> Value {
32    match value {
33        Value::Blank => Value::Boolean(Boolean::True),
34        Value::Text(s) => {
35            if s.is_empty() {
36                Value::Boolean(Boolean::True)
37            } else {
38                Value::Boolean(Boolean::False)
39            }
40        }
41        Value::Error(ValueError::Value) => Value::Boolean(Boolean::True),
42        Value::Error(ValueError::Reference) => Value::Boolean(Boolean::True),
43        _ => Value::Boolean(Boolean::False),
44    }
45}
46
47pub fn calculate_bool(
48    mut exp: Expression,
49    f: Option<&impl Fn(&str) -> Value>,
50    f_bool: fn(bool1: bool, bool2: bool) -> bool,
51) -> Value {
52    let mut result = match exp.values.pop() {
53        Some(formula) => calculate_formula(formula, f),
54        None => Value::Error(ValueError::Argument),
55    };
56    result = cast_value_to_boolean(result);
57    while let Some(top) = exp.values.pop() {
58        result = calculate_boolean_operator(result, calculate_formula(top, f), f_bool);
59    }
60    convert_iterator_to_result(result, f_bool)
61}
62
63pub fn calculate_or(
64    mut exp: Expression,
65    f: Option<&impl Fn(&str) -> Value>,
66    f_bool: fn(bool1: bool, bool2: bool) -> bool,
67) -> Value {
68    let mut result = match exp.values.pop() {
69        Some(formula) => calculate_formula(formula, f),
70        None => Value::Error(ValueError::Argument),
71    };
72    result = cast_value_to_boolean(result);
73    while let Some(top) = exp.values.pop() {
74        result = calculate_boolean_operator_or(result, calculate_formula(top, f), f_bool);
75    }
76    convert_iterator_to_result_or(result, f_bool)
77}
78
79pub fn calculate_xor(
80    mut exp: Expression,
81    f: Option<&impl Fn(&str) -> Value>,
82    f_bool: fn(bool1: bool, bool2: bool) -> bool,
83) -> Value {
84    let mut result = match exp.values.pop() {
85        Some(formula) => calculate_formula(formula, f),
86        None => Value::Error(ValueError::Argument),
87    };
88    result = cast_value_to_boolean(result);
89    while let Some(top) = exp.values.pop() {
90        result = calculate_boolean_operator_xor(result, calculate_formula(top, f), f_bool);
91    }
92    convert_iterator_to_result_xor(result, f_bool)
93}
94// Implement other logical functions here