From 18dc4db469737557da451a0f405fd90f672ac903 Mon Sep 17 00:00:00 2001 From: Yaroslav Bolyukin Date: Tue, 11 Jun 2024 14:22:38 +0200 Subject: [PATCH] fix: experimental features build --- cmds/jrsonnet/src/main.rs | 8 +++++-- crates/jrsonnet-stdlib/src/arrays.rs | 8 ++++++- crates/jrsonnet-stdlib/src/misc.rs | 35 +++++++++++++++++++++++++--- 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/cmds/jrsonnet/src/main.rs b/cmds/jrsonnet/src/main.rs index 105e94fb..415b9435 100644 --- a/cmds/jrsonnet/src/main.rs +++ b/cmds/jrsonnet/src/main.rs @@ -186,8 +186,12 @@ fn main_real(opts: Opts) -> Result<(), Error> { }; let tla = opts.tla.tla_opts()?; - #[allow(unused_mut)] - let mut val = apply_tla(s, &tla, val)?; + #[allow( + // It is not redundant/unused in exp-apply + unused_mut, + clippy::redundant_clone, + )] + let mut val = apply_tla(s.clone(), &tla, val)?; #[cfg(feature = "exp-apply")] for apply in opts.input.exp_apply { diff --git a/crates/jrsonnet-stdlib/src/arrays.rs b/crates/jrsonnet-stdlib/src/arrays.rs index a82a81bf..effa8dca 100644 --- a/crates/jrsonnet-stdlib/src/arrays.rs +++ b/crates/jrsonnet-stdlib/src/arrays.rs @@ -70,7 +70,13 @@ pub fn builtin_map_with_index(func: FuncVal, arr: IndexableVal) -> ArrValue { #[builtin] pub fn builtin_map_with_key(func: FuncVal, obj: ObjValue) -> Result { let mut out = ObjValueBuilder::new(); - for (k, v) in obj.iter() { + for (k, v) in obj.iter( + // Makes sense mapped object should be ordered the same way, should not break anything when the output is not ordered (the default). + // The thrown error might be different, but jsonnet + // does not specify the evaluation order. + #[cfg(feature = "exp-preserve-order")] + true, + ) { let v = v?; out.field(k.clone()) .value(func.evaluate_simple(&(k, v), false)?); diff --git a/crates/jrsonnet-stdlib/src/misc.rs b/crates/jrsonnet-stdlib/src/misc.rs index d9a0051e..8c1c813c 100644 --- a/crates/jrsonnet-stdlib/src/misc.rs +++ b/crates/jrsonnet-stdlib/src/misc.rs @@ -147,7 +147,14 @@ pub fn builtin_assert_equal(a: Val, b: Val) -> Result { if equals(&a, &b)? { return Ok(true); } - let format = JsonFormat::std_to_json(" ".to_owned(), "\n", ": "); + // TODO: Use debug output format + let format = JsonFormat::std_to_json( + " ".to_owned(), + "\n", + ": ", + #[cfg(feature = "exp-preserve-order")] + true, + ); let a = a.manifest(&format).description(" manifestification")?; let b = b.manifest(&format).description(" manifestification")?; bail!("assertion failed: A != B\nA: {a}\nB: {b}") @@ -161,8 +168,30 @@ pub fn builtin_merge_patch(target: Val, patch: Val) -> Result { let Some(target) = target.as_obj() else { return Ok(Val::Obj(patch)); }; - let target_fields = target.fields().into_iter().collect::>(); - let patch_fields = patch.fields().into_iter().collect::>(); + let target_fields = target + .fields( + // FIXME: Makes no sense to preserve order for BTreeSet, it would be better to use IndexSet here? + // But IndexSet won't allow fast ordered union... + // // Makes sense to preserve source ordering where possible. + // // May affect evaluation order, but it is not specified by jsonnet spec. + // #[cfg(feature = "exp-preserve-order")] + // true, + #[cfg(feature = "exp-preserve-order")] + false, + ) + .into_iter() + .collect::>(); + let patch_fields = patch + .fields( + // No need to look at the patch field order, I think? + // New fields (that will be appended at the end) will be alphabeticaly-ordered, + // but it is fine for jsonpatch, I don't think people write jsonpatch in jsonnet, + // when they can use mixins. + #[cfg(feature = "exp-preserve-order")] + false, + ) + .into_iter() + .collect::>(); let mut out = ObjValueBuilder::new(); for field in target_fields.union(&patch_fields) {