json_eval_rs/rlogic/evaluator/
logical.rs

1use super::Evaluator;
2use serde_json::Value;
3use super::super::compiled::CompiledLogic;
4use super::helpers;
5
6impl Evaluator {
7    /// Helper for And/Or logical operations in main eval context
8    /// Implements short-circuit evaluation matching JS behavior:
9    /// - OR (||): returns first truthy value, or last value if all falsy
10    /// - AND (&&): returns first falsy value, or last value if all truthy
11    #[inline]
12    pub(super) fn eval_and_or(&self, items: &[CompiledLogic], is_and: bool, user_data: &Value, internal_context: &Value, depth: usize) -> Result<Value, String> {
13        if items.is_empty() {
14            return Ok(Value::Bool(is_and));
15        }
16        
17        let mut last_result = Value::Null;
18        for item in items {
19            last_result = self.evaluate_with_context(item, user_data, internal_context, depth + 1)?;
20            let truthy = helpers::is_truthy(&last_result);
21            
22            // Short-circuit evaluation:
23            // AND: return first falsy value
24            // OR: return first truthy value
25            if is_and && !truthy {
26                return Ok(last_result);
27            } else if !is_and && truthy {
28                return Ok(last_result);
29            }
30        }
31        
32        // Return the last evaluated value
33        Ok(last_result)
34    }
35
36}