use serde_json::Value;
use std::borrow::Cow;
use std::collections::HashMap;
use super::helpers::{check_invalid_args_marker, is_truthy};
use crate::trace::TraceCollector;
use crate::{CompiledNode, ContextStack, DataLogic, Result};
#[inline(always)]
pub fn evaluate_not(
args: &[CompiledNode],
context: &mut ContextStack,
engine: &DataLogic,
) -> Result<Value> {
if args.is_empty() {
return Ok(Value::Bool(true)); }
let value = engine.evaluate_node_cow(&args[0], context)?;
Ok(Value::Bool(!is_truthy(&value, engine)))
}
#[inline(always)]
pub fn evaluate_double_not(
args: &[CompiledNode],
context: &mut ContextStack,
engine: &DataLogic,
) -> Result<Value> {
if args.is_empty() {
return Ok(Value::Bool(false)); }
let value = engine.evaluate_node_cow(&args[0], context)?;
Ok(Value::Bool(is_truthy(&value, engine)))
}
#[inline]
pub fn evaluate_and(
args: &[CompiledNode],
context: &mut ContextStack,
engine: &DataLogic,
) -> Result<Value> {
if args.is_empty() {
return Ok(Value::Null);
}
check_invalid_args_marker(args)?;
let mut last_value: Cow<'_, Value> = Cow::Owned(Value::Bool(true));
for arg in args {
let value = engine.evaluate_node_cow(arg, context)?;
if !is_truthy(&value, engine) {
return Ok(value.into_owned());
}
last_value = value;
}
Ok(last_value.into_owned())
}
#[inline]
pub fn evaluate_or(
args: &[CompiledNode],
context: &mut ContextStack,
engine: &DataLogic,
) -> Result<Value> {
if args.is_empty() {
return Ok(Value::Null);
}
check_invalid_args_marker(args)?;
let mut last_value: Cow<'_, Value> = Cow::Owned(Value::Bool(false));
for arg in args {
let value = engine.evaluate_node_cow(arg, context)?;
if is_truthy(&value, engine) {
return Ok(value.into_owned());
}
last_value = value;
}
Ok(last_value.into_owned())
}
#[inline(never)]
pub fn evaluate_and_traced(
args: &[CompiledNode],
context: &mut ContextStack,
engine: &DataLogic,
collector: &mut TraceCollector,
node_id_map: &HashMap<usize, u32>,
) -> Result<Value> {
if args.is_empty() {
return Ok(Value::Null);
}
check_invalid_args_marker(args)?;
let mut last_value = Value::Bool(true);
for arg in args {
let value = engine.evaluate_node_traced(arg, context, collector, node_id_map)?;
if !is_truthy(&value, engine) {
return Ok(value);
}
last_value = value;
}
Ok(last_value)
}
#[inline(never)]
pub fn evaluate_or_traced(
args: &[CompiledNode],
context: &mut ContextStack,
engine: &DataLogic,
collector: &mut TraceCollector,
node_id_map: &HashMap<usize, u32>,
) -> Result<Value> {
if args.is_empty() {
return Ok(Value::Null);
}
check_invalid_args_marker(args)?;
let mut last_value = Value::Bool(false);
for arg in args {
let value = engine.evaluate_node_traced(arg, context, collector, node_id_map)?;
if is_truthy(&value, engine) {
return Ok(value);
}
last_value = value;
}
Ok(last_value)
}