Skip to main content

jsonlogic/operators/
all.rs

1use serde_json::Value;
2
3use super::{logic, Data, Expression};
4
5/// Takes an array as the first argument and a condition as the second argument. Returns `true`
6/// if the condition evaluates to a truthy value for each element of the first parameter.
7///
8/// `var` operations inside the second argument expression are relative to the array element
9/// being tested.
10pub fn compute(args: &[Expression], data: &Data) -> Value {
11    let arr = match args.get(0).map(|arg| arg.compute(data)) {
12        Some(Value::Array(arr)) => arr,
13        // Due to an implementation detail `all` also works on strings. Applying the condition on
14        // each character on the string.
15        Some(Value::String(s)) => s.chars().map(|ch| Value::String(ch.to_string())).collect(),
16        _ => return Value::Bool(false),
17    };
18
19    if arr.len() == 0 {
20        return Value::Bool(false);
21    }
22
23    let condition = match args.get(1) {
24        Some(expr) => expr,
25        None => return Value::Bool(false),
26    };
27
28    for elem in arr.iter() {
29        let result = condition.compute(&Data::from_json(&elem));
30        if !logic::is_truthy(&result) {
31            return Value::Bool(false);
32        }
33    }
34
35    // Condition is truthy for all elements.
36    Value::Bool(true)
37}