git.delta.rocks / jrsonnet / refs/commits / 46b4dd0e38ba

difftreelog

perf make flatMap builtin

Yaroslav Bolyukin2021-07-12parent: #81202f5.patch.diff
in: master

2 files changed

modifiedcrates/jrsonnet-evaluator/src/builtin/mod.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/builtin/mod.rs
+++ b/crates/jrsonnet-evaluator/src/builtin/mod.rs
@@ -92,6 +92,7 @@
 			("native".into(), builtin_native),
 			("filter".into(), builtin_filter),
 			("map".into(), builtin_map),
+			("flatMap".into(), builtin_flatmap),
 			("foldl".into(), builtin_foldl),
 			("foldr".into(), builtin_foldr),
 			("sortImpl".into(), builtin_sort_impl),
@@ -331,6 +332,40 @@
 	})
 }
 
+fn builtin_flatmap(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {
+	parse_args!(context, "flatMap", args, 2, [
+		0, func: ty!(function) => Val::Func;
+		1, arr: ty!((array | string));
+	], {
+		match arr {
+			Val::Str(s) => {
+				let mut out = String::new();
+				for c in s.chars() {
+					match func.evaluate_values(context.clone(), &[Val::Str(c.to_string().into())])? {
+						Val::Str(o) => out.push_str(&o),
+						_ => throw!(RuntimeError("in std.join all items should be strings".into())),
+					};
+				}
+				Ok(Val::Str(out.into()))
+			},
+			Val::Arr(a) => {
+				let mut out = Vec::new();
+				for el in a.iter() {
+					let el = el?;
+					match func.evaluate_values(context.clone(), &[el])? {
+						Val::Arr(o) => for oe in o.iter() {
+							out.push(oe?)
+						},
+						_ => throw!(RuntimeError("in std.join all items should be arrays".into())),
+					};
+				}
+				Ok(Val::Arr(out.into()))
+			},
+			_ => unreachable!(),
+		}
+	})
+}
+
 fn builtin_foldl(context: Context, _loc: Option<&ExprLocation>, args: &ArgsDesc) -> Result<Val> {
 	parse_args!(context, "foldl", args, 3, [
 		0, func: ty!(function) => Val::Func;
modifiedcrates/jrsonnet-stdlib/src/std.jsonnetdiffbeforeafterboth
188 else188 else
189 { [k]: func(k, obj[k]) for k in std.objectFields(obj) },189 { [k]: func(k, obj[k]) for k in std.objectFields(obj) },
190190
191 flatMap(func, arr)::191 flatMap:: $intrinsic(flatMap),
192 if !std.isFunction(func) then
193 error ('std.flatMap first param must be function, got ' + std.type(func))
194 else if std.isArray(arr) then
195 std.flattenArrays(std.makeArray(std.length(arr), function(i) func(arr[i])))
196 else if std.isString(arr) then
197 std.join('', std.makeArray(std.length(arr), function(i) func(arr[i])))
198 else error ('std.flatMap second param must be array / string, got ' + std.type(arr)),
199192
200 join:: $intrinsic(join),193 join:: $intrinsic(join),
201194