git.delta.rocks / jrsonnet / refs/commits / f20aa2452d6c

difftreelog

feat allow iteration over objects in comprehensions

Yaroslav Bolyukin2022-11-09parent: #1b7795b.patch.diff
in: master
exp-object-iteration feature

3 files changed

modifiedcmds/jrsonnet/Cargo.tomldiffbeforeafterboth
17]17]
18# Destructuring of locals18# Destructuring of locals
19exp-destruct = ["jrsonnet-evaluator/exp-destruct"]19exp-destruct = ["jrsonnet-evaluator/exp-destruct"]
20# Iteration over objects yields [key, value] elements
21exp-object-iteration = ["jrsonnet-evaluator/exp-object-iteration"]
22
20# std.thisFile support23# std.thisFile support
21legacy-this-file = ["jrsonnet-cli/legacy-this-file"]24legacy-this-file = ["jrsonnet-cli/legacy-this-file"]
modifiedcrates/jrsonnet-evaluator/Cargo.tomldiffbeforeafterboth
20exp-preserve-order = []20exp-preserve-order = []
21# Implements field destructuring21# Implements field destructuring
22exp-destruct = ["jrsonnet-parser/exp-destruct"]22exp-destruct = ["jrsonnet-parser/exp-destruct"]
23# Iteration over objects yields [key, value] elements
24exp-object-iteration = []
25
23# Improves performance, and implements some useful things using nightly-only features26# Improves performance, and implements some useful things using nightly-only features
24nightly = []27nightly = []
modifiedcrates/jrsonnet-evaluator/src/evaluate/mod.rsdiffbeforeafterboth
66 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 = ctx
72 .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;
93
94 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 }
100
101 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 = ctx
112 .clone()
113 .extend(new_bindings, None, None, None)
114 .into_future(fctx);
115
116 evaluate_comp(ctx, &specs[1..], callback)?;
117 }
118 }
79 _ => throw!(InComprehensionCanOnlyIterateOverArray),119 _ => throw!(InComprehensionCanOnlyIterateOverArray),
80 },120 },
81 }121 }
99139
100 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)?;