///|
/// Evaluate array sum
fn eval_add(input : Json) -> Iter[Json] raise InterpreterError {
// jq defines `add` as `reduce .[] as $x (null; . + $x)`, so it also
// accepts objects (adding their values).
let values : Array[Json] = match input {
Array(arr) => arr
Object(obj) => obj.values().collect()
_ => raise TypeMismatch("array", @ast_internal.json_type_name(input))
}
Iter::singleton(values.fold(init=Json::null(), json_add))
}
///|
/// Evaluate floor
fn eval_floor(input : Json) -> Iter[Json] raise InterpreterError {
guard input is Number(n, ..) else {
raise TypeMismatch("number", @ast_internal.json_type_name(input))
}
Iter::singleton(Json::number(n.floor()))
}
///|
/// Evaluate square root
fn eval_sqrt(input : Json) -> Iter[Json] raise InterpreterError {
guard input is Number(n, ..) else {
raise TypeMismatch("number", @ast_internal.json_type_name(input))
}
Iter::singleton(Json::number(n.sqrt()))
}
///|
/// Evaluate minimum over array
fn eval_min(input : Json) -> Iter[Json] raise InterpreterError {
guard input is Array(arr) else {
raise TypeMismatch("array", @ast_internal.json_type_name(input))
}
Iter::singleton(min_in_view(arr).unwrap_or(null))
}
///|
/// Evaluate maximum over array
fn eval_max(input : Json) -> Iter[Json] raise InterpreterError {
guard input is Array(arr) else {
raise TypeMismatch("array", @ast_internal.json_type_name(input))
}
Iter::singleton(max_in_view(arr).unwrap_or(null))
}
///|
fn min_in_view(arr : ArrayView[Json]) -> Json? {
arr.fold(init=None, fn(min_val : Json?, value) {
match min_val {
None => Some(value)
Some(current) =>
if compare_json(value, current) < 0 {
Some(value)
} else {
min_val
}
}
})
}
///|
fn max_in_view(arr : ArrayView[Json]) -> Json? {
arr.fold(init=None, fn(max_val : Json?, value) {
match max_val {
None => Some(value)
Some(current) =>
if compare_json(value, current) > 0 {
Some(value)
} else {
max_val
}
}
})
}