git.delta.rocks / jrsonnet / refs/commits / 747b2b782cb8

difftreelog

perf make std.splitLimit builtin

Yaroslav Bolyukin2021-07-12parent: #02b7991.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
@@ -121,6 +121,7 @@
 			("reverse".into(), builtin_reverse),
 			("id".into(), builtin_id),
 			("strReplace".into(), builtin_str_replace),
+			("splitLimit".into(), builtin_splitlimit),
 			("parseJson".into(), builtin_parse_json),
 		].iter().cloned().collect()
 	};
@@ -751,6 +752,29 @@
 	})
 }
 
+fn builtin_splitlimit(
+	context: Context,
+	_loc: Option<&ExprLocation>,
+	args: &ArgsDesc,
+) -> Result<Val> {
+	parse_args!(context, "splitLimit", args, 3, [
+		0, str: ty!(string) => Val::Str;
+		1, c: ty!(char) => Val::Str;
+		2, maxsplits: ty!(number) => Val::Num;
+	], {
+		let maxsplits = maxsplits as isize;
+		let c = c.chars().next().unwrap();
+
+		let out: Vec<Val> = if maxsplits == -1 {
+			str.split(c).map(|s| Val::Str(s.into())).collect()
+		} else {
+			str.splitn(maxsplits as usize + 1, c).map(|s| Val::Str(s.into())).collect()
+		};
+
+		Ok(Val::Arr(out.into()))
+	})
+}
+
 pub fn call_builtin(
 	context: Context,
 	loc: Option<&ExprLocation>,
modifiedcrates/jrsonnet-stdlib/src/std.jsonnetdiffbeforeafterboth
123 assert std.length(c) == 1 : 'std.split second parameter should have length 1, got ' + std.length(c);123 assert std.length(c) == 1 : 'std.split second parameter should have length 1, got ' + std.length(c);
124 std.splitLimit(str, c, -1),124 std.splitLimit(str, c, -1),
125125
126 splitLimit(str, c, maxsplits)::126 splitLimit:: $intrinsic(splitLimit),
127 assert std.isString(str) : 'std.splitLimit first parameter should be a string, got ' + std.type(str);
128 assert std.isString(c) : 'std.splitLimit second parameter should be a string, got ' + std.type(c);
129 assert std.length(c) == 1 : 'std.splitLimit second parameter should have length 1, got ' + std.length(c);
130 assert std.isNumber(maxsplits) : 'std.splitLimit third parameter should be a number, got ' + std.type(maxsplits);
131 local aux(str, delim, i, arr, v) =
132 local c = str[i];
133 local i2 = i + 1;
134 if i >= std.length(str) then
135 arr + [v]
136 else if c == delim && (maxsplits == -1 || std.length(arr) < maxsplits) then
137 aux(str, delim, i2, arr + [v], '') tailstrict
138 else
139 aux(str, delim, i2, arr, v + c) tailstrict;
140 aux(str, c, 0, [], ''),
141127
142 strReplace:: $intrinsic(strReplace),128 strReplace:: $intrinsic(strReplace),
143129