git.delta.rocks / jrsonnet / refs/commits / 480843191a79

difftreelog

feat DestructRest in object destructuring

prkunoywYaroslav Bolyukin2026-03-23parent: #0afd461.patch.diff
in: master

2 files changed

modifiedcrates/jrsonnet-evaluator/src/evaluate/destructure.rsdiffbeforeafterboth
--- a/crates/jrsonnet-evaluator/src/evaluate/destructure.rs
+++ b/crates/jrsonnet-evaluator/src/evaluate/destructure.rs
@@ -107,6 +107,11 @@
 		}
 		#[cfg(feature = "exp-destruct")]
 		Destruct::Object { fields, rest } => {
+			use crate::ObjValueBuilder;
+			use jrsonnet_ir::DestructRest;
+			use rustc_hash::FxHashSet;
+
+			let captured_fields: FxHashSet<_> = fields.iter().map(|f| f.0.clone()).collect();
 			let field_names: Vec<_> = fields
 				.iter()
 				.map(|f| (f.0.clone(), f.2.is_some()))
@@ -131,6 +136,27 @@
 				Ok(obj)
 			});
 
+			match rest {
+				Some(DestructRest::Keep(v)) => {
+					let full = full.clone();
+					destruct(
+						&Destruct::Full(v.clone()),
+						Thunk!(move || {
+							let full = full.evaluate()?;
+							let mut builder = ObjValueBuilder::new();
+							builder
+								.reserve_cores(1)
+								.extend_with_core(full.as_standalone());
+							builder.with_fields_omitted(captured_fields);
+							Ok(Val::Obj(builder.build()))
+						}),
+						fctx.clone(),
+						new_bindings,
+					)?;
+				}
+				Some(DestructRest::Drop) | None => {}
+			}
+
 			for (field, d, default) in fields {
 				let default = default.clone().map(|e| (fctx.clone(), e));
 				let value = {
modifiedcrates/jrsonnet-evaluator/src/obj/mod.rsdiffbeforeafterboth
158pub type EnumFieldsHandler<'a> =158pub type EnumFieldsHandler<'a> =
159 dyn FnMut(SuperDepth, FieldIndex, IStr, EnumFields) -> ControlFlow<()> + 'a;159 dyn FnMut(SuperDepth, FieldIndex, IStr, EnumFields) -> ControlFlow<()> + 'a;
160160
161#[derive(Debug)]
161pub enum EnumFields {162pub enum EnumFields {
162 Normal(Visibility),163 Normal(Visibility),
163 Omit(Skip),164 Omit(Skip),
289}290}
290291
291#[derive(Trace, Debug)]292#[derive(Trace, Debug)]
292struct StandaloneSuperCore {293pub(crate) struct StandaloneSuperCore {
293 sup: CoreIdx,294 sup: CoreIdx,
294 this: ObjValue,295 this: ObjValue,
295}296}
791 key,792 key,
792 })793 })
793 }794 }
795 pub(crate) fn as_standalone(&self) -> StandaloneSuperCore {
796 StandaloneSuperCore {
797 sup: CoreIdx {
798 idx: self.0.cores.len(),
799 },
800 this: self.clone(),
801 }
802 }
794 pub fn ptr_eq(a: &Self, b: &Self) -> bool {803 pub fn ptr_eq(a: &Self, b: &Self) -> bool {
795 Cc::ptr_eq(&a.0, &b.0)804 Cc::ptr_eq(&a.0, &b.0)
796 }805 }