difftreelog
feat std.member and std.count builtin
in: master
3 files changed
crates/jrsonnet-evaluator/src/builtin/mod.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/builtin/mod.rs
+++ b/crates/jrsonnet-evaluator/src/builtin/mod.rs
@@ -128,6 +128,8 @@
("parseJson".into(), builtin_parse_json),
("asciiUpper".into(), builtin_ascii_upper),
("asciiLower".into(), builtin_ascii_lower),
+ ("member".into(), builtin_member),
+ ("count".into(), builtin_count),
].iter().cloned().collect()
};
}
@@ -854,6 +856,46 @@
})
}
+fn builtin_member(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {
+ parse_args!(context, "member", args, 2, [
+ 0, arr: ty!((array | string));
+ 1, x: ty!(any);
+ ], {
+ match arr {
+ Val::Str(s) => {
+ let x = x.try_cast_str("x should be string")?;
+ Ok(Val::Bool(!x.is_empty() && s.contains(&*x)))
+ }
+ Val::Arr(a) => {
+ for item in a.iter() {
+ let item = item?;
+ if equals(&item, &x)? {
+ return Ok(Val::Bool(true));
+ }
+ }
+ Ok(Val::Bool(false))
+ }
+ _ => unreachable!(),
+ }
+ })
+}
+
+fn builtin_count(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {
+ parse_args!(context, "count", args, 2, [
+ 0, arr: ty!(array) => Val::Arr;
+ 1, x: ty!(any);
+ ], {
+ let mut count = 0;
+ for item in arr.iter() {
+ let item = item?;
+ if equals(&item, &x)? {
+ count += 1;
+ }
+ }
+ Ok(Val::Num(count as f64))
+ })
+}
+
pub fn call_builtin(
context: Context,
loc: Option<&ExprLocation>,
crates/jrsonnet-evaluator/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/lib.rs
+++ b/crates/jrsonnet-evaluator/src/lib.rs
@@ -1051,4 +1051,21 @@
assert_eval!(r#"std.assertEqual(std.asciiUpper("aBc😀"), "ABC😀")"#);
assert_eval!(r#"std.assertEqual(std.asciiLower("aBc😀"), "abc😀")"#);
}
+
+ #[test]
+ fn test_member() {
+ assert_eval!(r#"!std.member("", "")"#);
+ assert_eval!(r#"std.member("abc", "a")"#);
+ assert_eval!(r#"!std.member("abc", "d")"#);
+ assert_eval!(r#"!std.member([], "")"#);
+ assert_eval!(r#"std.member(["a", "b", "c"], "a")"#);
+ assert_eval!(r#"!std.member(["a", "b", "c"], "d")"#);
+ }
+
+ #[test]
+ fn test_count() {
+ assert_eval!(r#"std.assertEqual(std.count([], ""), 0)"#);
+ assert_eval!(r#"std.assertEqual(std.count(["a", "b", "a"], "d"), 0)"#);
+ assert_eval!(r#"std.assertEqual(std.count(["a", "b", "a"], "a"), 2)"#);
+ }
}
crates/jrsonnet-stdlib/src/std.jsonnetdiffbeforeafterboth143143144 slice:: $intrinsic(slice),144 slice:: $intrinsic(slice),145145146 member(arr, x)::146 member:: $intrinsic(member),147 if std.isArray(arr) then148 std.count(arr, x) > 0149 else if std.isString(arr) then150 std.length(std.findSubstr(x, arr)) > 0151 else error 'std.member first argument must be an array or a string',152147153 count(arr, x):: std.length(std.filter(function(v) v == x, arr)),148 count:: $intrinsic(count),154149155 mod:: $intrinsic(mod),150 mod:: $intrinsic(mod),156151