difftreelog
perf faster strReplace
in: master
2 files changed
crates/jrsonnet-evaluator/build.rsdiffbeforeafterboth1use bincode::serialize;2use jrsonnet_parser::{3 parse, Expr, FieldMember, FieldName, LocExpr, Member, ObjBody, ParserSettings,4};5use jrsonnet_stdlib::STDLIB_STR;6use std::{7 env,8 fs::File,9 io::Write,10 path::{Path, PathBuf},11 rc::Rc,12};1314fn main() {15 let parsed = parse(16 STDLIB_STR,17 &ParserSettings {18 file_name: Rc::new(PathBuf::from("std.jsonnet")),19 loc_data: true,20 },21 )22 .expect("parse");2324 let parsed = if cfg!(feature = "faster") {25 let LocExpr(expr, location) = parsed;26 LocExpr(27 Rc::new(match Rc::try_unwrap(expr).unwrap() {28 Expr::Obj(ObjBody::MemberList(members)) => Expr::Obj(ObjBody::MemberList(29 members30 .into_iter()31 .filter(|p| {32 !matches!(33 p,34 Member::Field(FieldMember {35 name: FieldName::Fixed(name),36 ..37 })38 if name == "join" || name == "manifestJsonEx" ||39 name == "escapeStringJson" || name == "equals" ||40 name == "base64" || name == "foldl" || name == "foldr" ||41 name == "sortImpl" || name == "format" || name == "range" ||42 name == "reverse" || name == "slice" || name == "mod"43 )44 })45 .collect(),46 )),47 _ => panic!("std value should be object"),48 }),49 location,50 )51 } else {52 parsed53 };54 {55 let out_dir = env::var("OUT_DIR").unwrap();56 let dest_path = Path::new(&out_dir).join("stdlib.bincode");57 let mut f = File::create(&dest_path).unwrap();58 f.write_all(&serialize(&parsed).unwrap()).unwrap();59 }60}crates/jrsonnet-evaluator/src/builtin/mod.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/builtin/mod.rs
+++ b/crates/jrsonnet-evaluator/src/builtin/mod.rs
@@ -73,6 +73,7 @@
("manifestJsonEx".into(), builtin_manifest_json_ex),
("reverse".into(), builtin_reverse),
("id".into(), builtin_id),
+ ("strReplace".into(), builtin_str_replace),
].iter().cloned().collect()
};
}
@@ -131,7 +132,7 @@
parse_args!(context, "codepoint", args, 1, [
0, str: ty!(char) => Val::Str;
], {
- Ok(Val::Num(str.chars().take(1).next().unwrap() as u32 as f64))
+ Ok(Val::Num(str.chars().next().unwrap() as u32 as f64))
})
}
@@ -557,6 +558,28 @@
})
}
+// faster
+fn builtin_str_replace(context: Context, _loc: &Option<ExprLocation>, args: &ArgsDesc) -> Result<Val> {
+ parse_args!(context, "strReplace", args, 3, [
+ 0, str: ty!(string) => Val::Str;
+ 1, from: ty!(string) => Val::Str;
+ 2, to: ty!(string) => Val::Str;
+ ], {
+ let mut out = String::new();
+ let mut last_idx = 0;
+ while let Some(idx) = (&str[last_idx..]).find(&from as &str) {
+ out.push_str(&str[last_idx..last_idx+idx]);
+ out.push_str(&to);
+ last_idx += idx + from.len();
+ }
+ if last_idx == 0 {
+ return Ok(Val::Str(str))
+ }
+ out.push_str(&str[last_idx..]);
+ Ok(Val::Str(out.into()))
+ })
+}
+
#[allow(clippy::cognitive_complexity)]
pub fn call_builtin(
context: Context,