use super::*;
#[allow(clippy::too_many_arguments)]
pub(super) fn eval_coalesce_traced(
args: &[Expr],
injected: Option<&EvalValue>,
record: &JsonValue,
context: Option<&JsonValue>,
out: &JsonValue,
base_path: &str,
locals: Option<&EvalLocals<'_>>,
collector: &mut TraceCollector,
) -> Result<EvalValue, TransformError> {
let total_len = args_len(args, injected);
if total_len == 0 {
return Err(TransformError::new(
TransformErrorKind::ExprError,
"expr.args must be a non-empty array",
)
.with_path(format!("{}.args", base_path)));
}
for index in 0..total_len {
let arg_path = format!("{}.args[{}]", base_path, index);
let value = eval_expr_at_index_traced(
index, args, injected, record, context, out, base_path, locals, collector,
)?;
emit_arg_eval(collector, &arg_path, index, &value);
match value {
EvalValue::Missing => continue,
EvalValue::Value(value) => {
if value.is_null() {
continue;
}
return Ok(EvalValue::Value(value));
}
}
}
Ok(EvalValue::Missing)
}
#[allow(clippy::too_many_arguments)]
pub(super) fn eval_bool_and_or_traced(
args: &[Expr],
injected: Option<&EvalValue>,
record: &JsonValue,
context: Option<&JsonValue>,
out: &JsonValue,
base_path: &str,
is_and: bool,
locals: Option<&EvalLocals<'_>>,
collector: &mut TraceCollector,
) -> Result<EvalValue, TransformError> {
let total_len = args_len(args, injected);
if total_len < 2 {
return Err(TransformError::new(
TransformErrorKind::ExprError,
"expr.args must contain at least two items",
)
.with_path(format!("{}.args", base_path)));
}
let mut saw_missing = false;
for index in 0..total_len {
let arg_path = format!("{}.args[{}]", base_path, index);
let value = eval_expr_at_index_traced(
index, args, injected, record, context, out, base_path, locals, collector,
)?;
emit_arg_eval(collector, &arg_path, index, &value);
match value {
EvalValue::Missing => {
saw_missing = true;
continue;
}
EvalValue::Value(value) => {
let flag = value_as_bool(&value, &arg_path)?;
if is_and {
if !flag {
return Ok(EvalValue::Value(JsonValue::Bool(false)));
}
} else if flag {
return Ok(EvalValue::Value(JsonValue::Bool(true)));
}
}
}
}
if saw_missing {
Ok(EvalValue::Missing)
} else {
Ok(EvalValue::Value(JsonValue::Bool(is_and)))
}
}