--- a/crates/jrsonnet-stdlib/src/arrays.rs +++ b/crates/jrsonnet-stdlib/src/arrays.rs @@ -276,6 +276,18 @@ } #[builtin] +pub fn builtin_find(value: Val, arr: ArrValue) -> Result> { + let mut out = Vec::new(); + for (i, ele) in arr.iter().enumerate() { + let ele = ele?; + if equals(&ele, &value)? { + out.push(i); + } + } + Ok(out) +} + +#[builtin] pub fn builtin_contains(arr: IndexableVal, elem: Val) -> Result { builtin_member(arr, elem) } --- a/crates/jrsonnet-stdlib/src/lib.rs +++ b/crates/jrsonnet-stdlib/src/lib.rs @@ -91,6 +91,7 @@ ("any", builtin_any::INST), ("all", builtin_all::INST), ("member", builtin_member::INST), + ("find", builtin_find::INST), ("contains", builtin_contains::INST), ("count", builtin_count::INST), ("avg", builtin_avg::INST), @@ -213,6 +214,7 @@ ("get", builtin_get::INST), ("startsWith", builtin_starts_with::INST), ("endsWith", builtin_ends_with::INST), + ("assertEqual", builtin_assert_equal::INST), // Sets ("setMember", builtin_set_member::INST), ("setInter", builtin_set_inter::INST), --- a/crates/jrsonnet-stdlib/src/misc.rs +++ b/crates/jrsonnet-stdlib/src/misc.rs @@ -7,7 +7,7 @@ manifest::JsonFormat, typed::{Either2, Either4}, val::{equals, ArrValue}, - Context, Either, IStr, ObjValue, Thunk, Val, + Context, Either, IStr, ObjValue, ResultExt, Thunk, Val, }; use crate::{extvar_source, Settings}; @@ -141,3 +141,14 @@ _ => bail!("both arguments should be of the same type"), }) } + +#[builtin] +pub fn builtin_assert_equal(a: Val, b: Val) -> Result { + if equals(&a, &b)? { + return Ok(true); + } + let format = JsonFormat::std_to_json(" ".to_owned(), "\n", ": "); + let a = a.manifest(&format).description(" manifestification")?; + let b = b.manifest(&format).description(" manifestification")?; + bail!("assertion failed: A != B\nA: {a}\nB: {b}") +} --- a/crates/jrsonnet-stdlib/src/std.jsonnet +++ b/crates/jrsonnet-stdlib/src/std.jsonnet @@ -11,12 +11,6 @@ else { [k]: func(k, obj[k]) for k in std.objectFields(obj) }, - assertEqual(a, b):: - if a == b then - true - else - error 'Assertion failed. ' + a + ' != ' + b, - mergePatch(target, patch):: if std.isObject(patch) then local target_object = @@ -44,10 +38,4 @@ resolvePath(f, r):: local arr = std.split(f, '/'); std.join('/', std.makeArray(std.length(arr) - 1, function(i) arr[i]) + [r]), - - find(value, arr):: - if !std.isArray(arr) then - error 'find second parameter should be an array, got ' + std.type(arr) - else - std.filter(function(i) arr[i] == value, std.range(0, std.length(arr) - 1)), }