git.delta.rocks / jrsonnet / refs/commits / 859b044c14c9

difftreelog

feat std.member and std.count builtin

messense2021-07-13parent: #07ae295.patch.diff
in: master

3 files changed

modifiedcrates/jrsonnet-evaluator/src/builtin/mod.rsdiffbeforeafterboth
128 ("parseJson".into(), builtin_parse_json),128 ("parseJson".into(), builtin_parse_json),
129 ("asciiUpper".into(), builtin_ascii_upper),129 ("asciiUpper".into(), builtin_ascii_upper),
130 ("asciiLower".into(), builtin_ascii_lower),130 ("asciiLower".into(), builtin_ascii_lower),
131 ("member".into(), builtin_member),
132 ("count".into(), builtin_count),
131 ].iter().cloned().collect()133 ].iter().cloned().collect()
132 };134 };
133}135}
854 })856 })
855}857}
858
859fn builtin_member(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {
860 parse_args!(context, "member", args, 2, [
861 0, arr: ty!((array | string));
862 1, x: ty!(any);
863 ], {
864 match arr {
865 Val::Str(s) => {
866 let x = x.try_cast_str("x should be string")?;
867 Ok(Val::Bool(!x.is_empty() && s.contains(&*x)))
868 }
869 Val::Arr(a) => {
870 for item in a.iter() {
871 let item = item?;
872 if equals(&item, &x)? {
873 return Ok(Val::Bool(true));
874 }
875 }
876 Ok(Val::Bool(false))
877 }
878 _ => unreachable!(),
879 }
880 })
881}
882
883fn builtin_count(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {
884 parse_args!(context, "count", args, 2, [
885 0, arr: ty!(array) => Val::Arr;
886 1, x: ty!(any);
887 ], {
888 let mut count = 0;
889 for item in arr.iter() {
890 let item = item?;
891 if equals(&item, &x)? {
892 count += 1;
893 }
894 }
895 Ok(Val::Num(count as f64))
896 })
897}
856898
857pub fn call_builtin(899pub fn call_builtin(
858 context: Context,900 context: Context,
modifiedcrates/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)"#);
+	}
 }
modifiedcrates/jrsonnet-stdlib/src/std.jsonnetdiffbeforeafterboth
--- a/crates/jrsonnet-stdlib/src/std.jsonnet
+++ b/crates/jrsonnet-stdlib/src/std.jsonnet
@@ -143,14 +143,9 @@
 
   slice:: $intrinsic(slice),
 
-  member(arr, x)::
-    if std.isArray(arr) then
-      std.count(arr, x) > 0
-    else if std.isString(arr) then
-      std.length(std.findSubstr(x, arr)) > 0
-    else error 'std.member first argument must be an array or a string',
+  member:: $intrinsic(member),
 
-  count(arr, x):: std.length(std.filter(function(v) v == x, arr)),
+  count:: $intrinsic(count),
 
   mod:: $intrinsic(mod),