difftreelog
feat allow iteration over objects in comprehensions
in: master
exp-object-iteration feature
3 files changed
cmds/jrsonnet/Cargo.tomldiffbeforeafterboth--- a/cmds/jrsonnet/Cargo.toml
+++ b/cmds/jrsonnet/Cargo.toml
@@ -17,6 +17,9 @@
]
# Destructuring of locals
exp-destruct = ["jrsonnet-evaluator/exp-destruct"]
+# Iteration over objects yields [key, value] elements
+exp-object-iteration = ["jrsonnet-evaluator/exp-object-iteration"]
+
# std.thisFile support
legacy-this-file = ["jrsonnet-cli/legacy-this-file"]
crates/jrsonnet-evaluator/Cargo.tomldiffbeforeafterboth--- a/crates/jrsonnet-evaluator/Cargo.toml
+++ b/crates/jrsonnet-evaluator/Cargo.toml
@@ -20,6 +20,9 @@
exp-preserve-order = []
# Implements field destructuring
exp-destruct = ["jrsonnet-parser/exp-destruct"]
+# Iteration over objects yields [key, value] elements
+exp-object-iteration = []
+
# Improves performance, and implements some useful things using nightly-only features
nightly = []
crates/jrsonnet-evaluator/src/evaluate/mod.rsdiffbeforeafterboth66 Val::Arr(list) => {66 Val::Arr(list) => {67 for item in list.iter_lazy() {67 for item in list.iter_lazy() {68 let fctx = Pending::new();68 let fctx = Pending::new();69 let mut new_bindings = GcHashMap::new();69 let mut new_bindings = GcHashMap::with_capacity(var.capacity_hint());70 destruct(var, item, fctx.clone(), &mut new_bindings)?;70 destruct(var, item, fctx.clone(), &mut new_bindings)?;71 let ctx = ctx71 let ctx = ctx72 .clone()72 .clone()76 evaluate_comp(ctx, &specs[1..], callback)?;76 evaluate_comp(ctx, &specs[1..], callback)?;77 }77 }78 }78 }79 #[cfg(feature = "exp-object-iteration")]80 Val::Obj(obj) => {81 for field in obj.fields(82 // TODO: Should there be ability to preserve iteration order?83 #[cfg(feature = "exp-preserve-order")]84 false,85 ) {86 #[derive(Trace)]87 struct ObjectFieldThunk {88 obj: ObjValue,89 field: IStr,90 }91 impl ThunkValue for ObjectFieldThunk {92 type Output = Val;9394 fn get(self: Box<Self>) -> Result<Self::Output> {95 self.obj.get(self.field).transpose().expect(96 "field exists, as field name was obtained from object.fields()",97 )98 }99 }100101 let fctx = Pending::new();102 let mut new_bindings = GcHashMap::with_capacity(var.capacity_hint());103 let value = Thunk::evaluated(Val::Arr(ArrValue::Lazy(Cc::new(vec![104 Thunk::evaluated(Val::Str(field.clone())),105 Thunk::new(tb!(ObjectFieldThunk {106 field: field.clone(),107 obj: obj.clone(),108 })),109 ]))));110 destruct(var, value, fctx.clone(), &mut new_bindings)?;111 let ctx = ctx112 .clone()113 .extend(new_bindings, None, None, None)114 .into_future(fctx);115116 evaluate_comp(ctx, &specs[1..], callback)?;117 }118 }79 _ => throw!(InComprehensionCanOnlyIterateOverArray),119 _ => throw!(InComprehensionCanOnlyIterateOverArray),80 },120 },81 }121 }99139100 fn bind(&self, sup: Option<ObjValue>, this: Option<ObjValue>) -> Result<Context> {140 fn bind(&self, sup: Option<ObjValue>, this: Option<ObjValue>) -> Result<Context> {101 let fctx = Context::new_future();141 let fctx = Context::new_future();102 let mut new_bindings = GcHashMap::new();142 let mut new_bindings =143 GcHashMap::with_capacity(self.locals.iter().map(BindSpec::capacity_hint).sum());103 for b in self.locals.iter() {144 for b in self.locals.iter() {104 evaluate_dest(b, fctx.clone(), &mut new_bindings)?;145 evaluate_dest(b, fctx.clone(), &mut new_bindings)?;105 }146 }446 },487 },447 LocalExpr(bindings, returned) => {488 LocalExpr(bindings, returned) => {448 let mut new_bindings: GcHashMap<IStr, Thunk<Val>> =489 let mut new_bindings: GcHashMap<IStr, Thunk<Val>> =449 GcHashMap::with_capacity(bindings.len());490 GcHashMap::with_capacity(bindings.iter().map(BindSpec::capacity_hint).sum());450 let fctx = Context::new_future();491 let fctx = Context::new_future();451 for b in bindings {492 for b in bindings {452 evaluate_dest(b, fctx.clone(), &mut new_bindings)?;493 evaluate_dest(b, fctx.clone(), &mut new_bindings)?;