difftreelog
perf implement std.prune in native
in: master
6 files changed
cmds/jrsonnet-fmt/src/main.rsdiffbeforeafterboth--- a/cmds/jrsonnet-fmt/src/main.rs
+++ b/cmds/jrsonnet-fmt/src/main.rs
@@ -356,16 +356,16 @@
impl Printable for Member {
fn print(&self, out: &mut PrintItems) {
match self {
- Member::MemberBindStmt(b) => {
+ Self::MemberBindStmt(b) => {
p!(out, { b.obj_local() })
}
- Member::MemberAssertStmt(ass) => {
+ Self::MemberAssertStmt(ass) => {
p!(out, { ass.assertion() })
}
- Member::MemberFieldNormal(n) => {
+ Self::MemberFieldNormal(n) => {
p!(out, {n.field_name()} if(n.plus_token().is_some())({n.plus_token()}) {n.visibility()} str(" ") {n.expr()})
}
- Member::MemberFieldMethod(m) => {
+ Self::MemberFieldMethod(m) => {
p!(out, {m.field_name()} {m.params_desc()} {m.visibility()} str(" ") {m.expr()})
}
}
crates/jrsonnet-evaluator/src/manifest.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/manifest.rs
+++ b/crates/jrsonnet-evaluator/src/manifest.rs
@@ -1,6 +1,6 @@
use std::{borrow::Cow, fmt::Write};
-use crate::{bail, Result, State, Val};
+use crate::{bail, Result, ResultExt, State, Val};
pub trait ManifestFormat {
fn manifest_buf(&self, val: Val, buf: &mut String) -> Result<()>;
@@ -235,7 +235,8 @@
}
}
buf.push_str(cur_padding);
- manifest_json_ex_buf(&item?, buf, cur_padding, options)?;
+ manifest_json_ex_buf(&item?, buf, cur_padding, options)
+ .with_description(|| format!("elem <{i}> manifestification"))?;
}
cur_padding.truncate(old_len);
crates/jrsonnet-evaluator/src/obj.rsdiffbeforeafterboth--- a/crates/jrsonnet-evaluator/src/obj.rs
+++ b/crates/jrsonnet-evaluator/src/obj.rs
@@ -278,7 +278,7 @@
}
impl ObjectLike for ThisOverride {
fn with_this(&self, _me: ObjValue, this: ObjValue) -> ObjValue {
- ObjValue::new(ThisOverride {
+ ObjValue::new(Self {
inner: self.inner.clone(),
this,
})
@@ -398,7 +398,7 @@
self.get_for(key, self.0.this().unwrap_or_else(|| self.clone()))
}
- pub fn get_for(&self, key: IStr, this: ObjValue) -> Result<Option<Val>> {
+ pub fn get_for(&self, key: IStr, this: Self) -> Result<Option<Val>> {
self.0.get_for(key, this)
}
@@ -410,7 +410,7 @@
Ok(value)
}
- fn get_raw(&self, key: IStr, this: ObjValue) -> Result<Option<Val>> {
+ fn get_raw(&self, key: IStr, this: Self) -> Result<Option<Val>> {
self.0.get_for_uncached(key, this)
}
@@ -422,7 +422,7 @@
// FIXME: Should it use `self.0.this()` in case of standalone super?
self.run_assertions_raw(self.clone())
}
- fn run_assertions_raw(&self, this: ObjValue) -> Result<()> {
+ fn run_assertions_raw(&self, this: Self) -> Result<()> {
self.0.run_assertions_raw(this)
}
crates/jrsonnet-stdlib/src/arrays.rsdiffbeforeafterboth1#![allow(non_snake_case)]23use jrsonnet_evaluator::{4 bail,5 function::{builtin, FuncVal},6 runtime_error,7 typed::{BoundedI32, BoundedUsize, Either2, NativeFn, Typed},8 val::{equals, ArrValue, IndexableVal},9 Either, IStr, Result, Thunk, Val,10};1112pub(crate) fn eval_on_empty(on_empty: Option<Thunk<Val>>) -> Result<Val> {13 if let Some(on_empty) = on_empty {14 on_empty.evaluate()15 } else {16 bail!("expected non-empty array")17 }18}1920#[builtin]21pub fn builtin_make_array(sz: BoundedI32<0, { i32::MAX }>, func: FuncVal) -> Result<ArrValue> {22 if *sz == 0 {23 return Ok(ArrValue::empty());24 }25 if let Some(trivial) = func.evaluate_trivial() {26 let mut out = Vec::with_capacity(*sz as usize);27 for _ in 0..*sz {28 out.push(trivial.clone())29 }30 Ok(ArrValue::eager(out))31 } else {32 Ok(ArrValue::range_exclusive(0, *sz).map(func))33 }34}3536#[builtin]37pub fn builtin_repeat(what: Either![IStr, ArrValue], count: usize) -> Result<Val> {38 Ok(match what {39 Either2::A(s) => Val::string(s.repeat(count)),40 Either2::B(arr) => Val::Arr(41 ArrValue::repeated(arr, count)42 .ok_or_else(|| runtime_error!("repeated length overflow"))?,43 ),44 })45}4647#[builtin]48pub fn builtin_slice(49 indexable: IndexableVal,50 index: Option<i32>,51 end: Option<i32>,52 step: Option<BoundedUsize<1, { i32::MAX as usize }>>,53) -> Result<Val> {54 indexable.slice(index, end, step).map(Val::from)55}5657#[builtin]58pub fn builtin_map(func: FuncVal, arr: IndexableVal) -> ArrValue {59 let arr = arr.to_array();60 arr.map(func)61}6263#[builtin]64pub fn builtin_flatmap(65 func: NativeFn<((Either![String, Val],), Val)>,66 arr: IndexableVal,67) -> Result<IndexableVal> {68 use std::fmt::Write;69 match arr {70 IndexableVal::Str(str) => {71 let mut out = String::new();72 for c in str.chars() {73 match func(Either2::A(c.to_string()))? {74 Val::Str(o) => write!(out, "{o}").unwrap(),75 Val::Null => continue,76 _ => bail!("in std.join all items should be strings"),77 };78 }79 Ok(IndexableVal::Str(out.into()))80 }81 IndexableVal::Arr(a) => {82 let mut out = Vec::new();83 for el in a.iter() {84 let el = el?;85 match func(Either2::B(el))? {86 Val::Arr(o) => {87 for oe in o.iter() {88 out.push(oe?);89 }90 }91 Val::Null => continue,92 _ => bail!("in std.join all items should be arrays"),93 };94 }95 Ok(IndexableVal::Arr(out.into()))96 }97 }98}99100#[builtin]101pub fn builtin_filter(func: FuncVal, arr: ArrValue) -> Result<ArrValue> {102 arr.filter(|val| bool::from_untyped(func.evaluate_simple(&(val.clone(),), false)?))103}104105#[builtin]106pub fn builtin_filter_map(107 filter_func: FuncVal,108 map_func: FuncVal,109 arr: ArrValue,110) -> Result<ArrValue> {111 Ok(builtin_filter(filter_func, arr)?.map(map_func))112}113114#[builtin]115pub fn builtin_foldl(func: FuncVal, arr: ArrValue, init: Val) -> Result<Val> {116 let mut acc = init;117 for i in arr.iter() {118 acc = func.evaluate_simple(&(acc, i?), false)?;119 }120 Ok(acc)121}122123#[builtin]124pub fn builtin_foldr(func: FuncVal, arr: ArrValue, init: Val) -> Result<Val> {125 let mut acc = init;126 for i in arr.iter().rev() {127 acc = func.evaluate_simple(&(i?, acc), false)?;128 }129 Ok(acc)130}131132#[builtin]133pub fn builtin_range(from: i32, to: i32) -> Result<ArrValue> {134 if to < from {135 return Ok(ArrValue::empty());136 }137 Ok(ArrValue::range_inclusive(from, to))138}139140#[builtin]141pub fn builtin_join(sep: IndexableVal, arr: ArrValue) -> Result<IndexableVal> {142 use std::fmt::Write;143 Ok(match sep {144 IndexableVal::Arr(joiner_items) => {145 let mut out = Vec::new();146147 let mut first = true;148 for item in arr.iter() {149 let item = item?.clone();150 if let Val::Arr(items) = item {151 if !first {152 out.reserve(joiner_items.len());153 // TODO: extend154 for item in joiner_items.iter() {155 out.push(item?);156 }157 }158 first = false;159 out.reserve(items.len());160 for item in items.iter() {161 out.push(item?);162 }163 } else if matches!(item, Val::Null) {164 continue;165 } else {166 bail!("in std.join all items should be arrays");167 }168 }169170 IndexableVal::Arr(out.into())171 }172 IndexableVal::Str(sep) => {173 let mut out = String::new();174175 let mut first = true;176 for item in arr.iter() {177 let item = item?.clone();178 if let Val::Str(item) = item {179 if !first {180 out += &sep;181 }182 first = false;183 write!(out, "{item}").unwrap()184 } else if matches!(item, Val::Null) {185 continue;186 } else {187 bail!("in std.join all items should be strings");188 }189 }190191 IndexableVal::Str(out.into())192 }193 })194}195196#[builtin]197pub fn builtin_reverse(arr: ArrValue) -> ArrValue {198 arr.reversed()199}200201#[builtin]202pub fn builtin_any(arr: ArrValue) -> Result<bool> {203 for v in arr.iter() {204 let v = bool::from_untyped(v?)?;205 if v {206 return Ok(true);207 }208 }209 Ok(false)210}211212#[builtin]213pub fn builtin_all(arr: ArrValue) -> Result<bool> {214 for v in arr.iter() {215 let v = bool::from_untyped(v?)?;216 if !v {217 return Ok(false);218 }219 }220 Ok(true)221}222223#[builtin]224pub fn builtin_member(arr: IndexableVal, x: Val) -> Result<bool> {225 match arr {226 IndexableVal::Str(str) => {227 let x: IStr = IStr::from_untyped(x)?;228 Ok(!x.is_empty() && str.contains(&*x))229 }230 IndexableVal::Arr(a) => {231 for item in a.iter() {232 let item = item?;233 if equals(&item, &x)? {234 return Ok(true);235 }236 }237 Ok(false)238 }239 }240}241242#[builtin]243pub fn builtin_contains(arr: IndexableVal, elem: Val) -> Result<bool> {244 builtin_member(arr, elem)245}246247#[builtin]248pub fn builtin_count(arr: ArrValue, x: Val) -> Result<usize> {249 let mut count = 0;250 for item in arr.iter() {251 if equals(&item?, &x)? {252 count += 1;253 }254 }255 Ok(count)256}257258#[builtin]259pub fn builtin_avg(arr: Vec<f64>, onEmpty: Option<Thunk<Val>>) -> Result<Val> {260 if arr.is_empty() {261 return eval_on_empty(onEmpty);262 }263 Ok(Val::Num(arr.iter().sum::<f64>() / (arr.len() as f64)))264}265266#[builtin]267pub fn builtin_remove_at(arr: ArrValue, at: usize) -> Result<ArrValue> {268 let newArrLeft = arr.clone().slice(None, Some(at), None);269 let newArrRight = arr.slice(Some(at + 1), None, None);270271 Ok(ArrValue::extended(272 newArrLeft.unwrap_or(ArrValue::empty()),273 newArrRight.unwrap_or(ArrValue::empty()),274 ))275}276277#[builtin]278pub fn builtin_remove(arr: ArrValue, elem: Val) -> Result<ArrValue> {279 for (index, item) in arr.iter().enumerate() {280 if equals(&item?, &elem)? {281 return builtin_remove_at(arr.clone(), index);282 }283 }284 Ok(arr)285}286287#[builtin]288pub fn builtin_flatten_arrays(arrs: Vec<ArrValue>) -> ArrValue {289 pub fn flatten_inner(values: &[ArrValue]) -> ArrValue {290 if values.len() == 1 {291 return values[0].clone();292 } else if values.len() == 2 {293 return ArrValue::extended(values[0].clone(), values[1].clone());294 }295 let (a, b) = values.split_at(values.len() / 2);296 ArrValue::extended(flatten_inner(a), flatten_inner(b))297 }298 if arrs.is_empty() {299 return ArrValue::empty();300 } else if arrs.len() == 1 {301 return arrs.into_iter().next().expect("single");302 }303 flatten_inner(&arrs)304}305306#[builtin]307pub fn builtin_flatten_deep_array(value: Val) -> Result<Vec<Val>> {308 fn process(value: Val, out: &mut Vec<Val>) -> Result<()> {309 match value {310 Val::Arr(arr) => {311 for ele in arr.iter() {312 process(ele?, out)?;313 }314 }315 _ => out.push(value),316 }317 Ok(())318 }319 let mut out = Vec::new();320 process(value, &mut out)?;321 Ok(out)322}crates/jrsonnet-stdlib/src/lib.rsdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/lib.rs
+++ b/crates/jrsonnet-stdlib/src/lib.rs
@@ -92,6 +92,7 @@
("remove", builtin_remove::INST),
("flattenArrays", builtin_flatten_arrays::INST),
("flattenDeepArray", builtin_flatten_deep_array::INST),
+ ("prune", builtin_prune::INST),
("filterMap", builtin_filter_map::INST),
// Math
("abs", builtin_abs::INST),
crates/jrsonnet-stdlib/src/std.jsonnetdiffbeforeafterboth--- a/crates/jrsonnet-stdlib/src/std.jsonnet
+++ b/crates/jrsonnet-stdlib/src/std.jsonnet
@@ -209,25 +209,6 @@
local arr = std.split(f, '/');
std.join('/', std.makeArray(std.length(arr) - 1, function(i) arr[i]) + [r]),
- prune(a)::
- local isContent(b) =
- if b == null then
- false
- else if std.isArray(b) then
- std.length(b) > 0
- else if std.isObject(b) then
- std.length(b) > 0
- else
- true;
- if std.isArray(a) then
- [std.prune(x) for x in a if isContent($.prune(x))]
- else if std.isObject(a) then {
- [x]: $.prune(a[x])
- for x in std.objectFields(a)
- if isContent(std.prune(a[x]))
- } else
- a,
-
find(value, arr)::
if !std.isArray(arr) then
error 'find second parameter should be an array, got ' + std.type(arr)