difftreelog
perf implement std.{startsWith, endsWith} in native
in: master
2 files changed
crates/jrsonnet-stdlib/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/lib.rs
+++ b/crates/jrsonnet-stdlib/src/lib.rs
@@ -9,9 +9,9 @@
error::{Error::*, Result},
function::{builtin::Builtin, ArgLike, CallLocation, FuncVal, TlaArg},
gc::TraceBox,
- tb,
+ tb, throw_runtime,
typed::{Any, Either, Either2, Either4, VecVal, M1},
- val::ArrValue,
+ val::{equals, ArrValue},
Context, ContextBuilder, IStr, ObjValue, ObjValueBuilder, State, Thunk, Val,
};
use jrsonnet_gcmodule::Cc;
@@ -129,6 +129,8 @@
("asciiUpper".into(), builtin_ascii_upper::INST),
("asciiLower".into(), builtin_ascii_lower::INST),
("findSubstr".into(), builtin_find_substr::INST),
+ ("startsWith".into(), builtin_starts_with::INST),
+ ("endsWith".into(), builtin_ends_with::INST),
]
.iter()
.cloned()
@@ -446,3 +448,68 @@
}
Ok(out.into())
}
+
+#[builtin]
+fn builtin_starts_with(
+ s: State,
+ a: Either![IStr, ArrValue],
+ b: Either![IStr, ArrValue],
+) -> Result<bool> {
+ Ok(match (a, b) {
+ (Either2::A(a), Either2::A(b)) => a.starts_with(b.as_str()),
+ (Either2::B(a), Either2::B(b)) => {
+ if b.len() > a.len() {
+ return Ok(false);
+ } else if b.len() == a.len() {
+ return equals(s, &Val::Arr(a), &Val::Arr(b));
+ } else {
+ for (a, b) in a
+ .slice(None, Some(b.len()), None)
+ .iter(s.clone())
+ .zip(b.iter(s.clone()))
+ {
+ let a = a?;
+ let b = b?;
+ if !equals(s.clone(), &a, &b)? {
+ return Ok(false);
+ }
+ }
+ true
+ }
+ }
+ _ => throw_runtime!("both arguments should be of the same type"),
+ })
+}
+
+#[builtin]
+fn builtin_ends_with(
+ s: State,
+ a: Either![IStr, ArrValue],
+ b: Either![IStr, ArrValue],
+) -> Result<bool> {
+ Ok(match (a, b) {
+ (Either2::A(a), Either2::A(b)) => a.ends_with(b.as_str()),
+ (Either2::B(a), Either2::B(b)) => {
+ if b.len() > a.len() {
+ return Ok(false);
+ } else if b.len() == a.len() {
+ return equals(s, &Val::Arr(a), &Val::Arr(b));
+ } else {
+ let a_len = a.len();
+ for (a, b) in a
+ .slice(Some(a_len - b.len()), None, None)
+ .iter(s.clone())
+ .zip(b.iter(s.clone()))
+ {
+ let a = a?;
+ let b = b?;
+ if !equals(s.clone(), &a, &b)? {
+ return Ok(false);
+ }
+ }
+ true
+ }
+ }
+ _ => throw_runtime!("both arguments should be of the same type"),
+ })
+}
crates/jrsonnet-stdlib/src/std.jsonnetdiffbeforeafterboth445 thisFile:: error 'std.thisFile is deprecated, to enable its support in jrsonnet - recompile it with "legacy-this-file" support. This will slow down stdlib caching a bit, though',5 thisFile:: error 'std.thisFile is deprecated, to enable its support in jrsonnet - recompile it with "legacy-this-file" support. This will slow down stdlib caching a bit, though',667 toString(a)::7 toString(a):: '' + a,8 if std.type(a) == 'string' then a else '' + a,9810 startsWith(a, b)::11 if std.length(a) < std.length(b) then12 false13 else14 std.substr(a, 0, std.length(b)) == b,1516 endsWith(a, b)::17 if std.length(a) < std.length(b) then18 false19 else20 std.substr(a, std.length(a) - std.length(b), std.length(b)) == b,2122 lstripChars(str, chars)::9 lstripChars(str, chars)::23 if std.length(str) > 0 && std.member(chars, str[0]) then10 if std.length(str) > 0 && std.member(chars, str[0]) then24 std.lstripChars(str[1:], chars)11 std.lstripChars(str[1:], chars)