From f3c8ed70f69fce3d623cecf550476a2a48182f7a Mon Sep 17 00:00:00 2001 From: Yaroslav Bolyukin Date: Sun, 05 Apr 2026 19:25:11 +0000 Subject: [PATCH] refactor: do not expose direct operator evaluator access --- --- a/crates/jrsonnet-evaluator/src/val.rs +++ b/crates/jrsonnet-evaluator/src/val.rs @@ -10,18 +10,14 @@ use jrsonnet_gcmodule::{Acyclic, Cc, Trace, cc_dyn}; use jrsonnet_interner::IStr; +use jrsonnet_ir::BinaryOpType; pub use jrsonnet_macros::Thunk; use jrsonnet_types::ValType; use rustc_hash::FxHashMap; pub use crate::arr::{ArrValue, ArrayLike}; use crate::{ - NumValue, ObjValue, Result, SupThis, Unbound, WeakSupThis, bail, - error::{Error, ErrorKind::*}, - function::FuncVal, - gc::WithCapacityExt as _, - manifest::{ManifestFormat, ToStringFormat}, - typed::BoundedUsize, + NumValue, ObjValue, Result, SupThis, Unbound, WeakSupThis, bail, error::{Error, ErrorKind::*}, evaluate::operator::{evaluate_compare_op, evaluate_mod_op}, function::FuncVal, gc::WithCapacityExt as _, manifest::{ManifestFormat, ToStringFormat}, typed::BoundedUsize }; pub trait ThunkValue: Trace { @@ -585,6 +581,13 @@ pub fn arr(a: impl ArrayLike) -> Self { Self::Arr(ArrValue::new(a)) } + + pub fn try_cmp(a: &Val, b: &Val) -> Result { + evaluate_compare_op(a, b, BinaryOpType::Lt) + } + pub fn try_mod(a: &Val, b: &Val) -> Result { + evaluate_mod_op(a, b) + } } impl From for Val { --- a/crates/jrsonnet-stdlib/Cargo.toml +++ b/crates/jrsonnet-stdlib/Cargo.toml @@ -16,17 +16,13 @@ # Bigint type exp-bigint = ["dep:num-bigint", "jrsonnet-evaluator/exp-bigint"] -exp-null-coaelse = [ - "jrsonnet-ir/exp-null-coaelse", - "jrsonnet-evaluator/exp-null-coaelse", -] +exp-null-coaelse = ["jrsonnet-evaluator/exp-null-coaelse"] # std.regexMatch and other helpers exp-regex = ["dep:regex", "dep:lru", "dep:rustc-hash"] [dependencies] jrsonnet-evaluator.workspace = true jrsonnet-macros.workspace = true -jrsonnet-ir.workspace = true jrsonnet-gcmodule.workspace = true # Used for std.parseJson/std.parseYaml --- a/crates/jrsonnet-stdlib/src/compat.rs +++ b/crates/jrsonnet-stdlib/src/compat.rs @@ -1,19 +1,15 @@ use std::cmp::Ordering; -use jrsonnet_evaluator::{ - Result, Val, function::builtin, operator::evaluate_compare_op, val::ArrValue, -}; +use jrsonnet_evaluator::{function::builtin, val::ArrValue, Result, Val}; #[builtin] #[allow(non_snake_case)] pub fn builtin___compare(v1: Val, v2: Val) -> Result { - Ok( - match evaluate_compare_op(&v1, &v2, jrsonnet_ir::BinaryOpType::Lt)? { - Ordering::Less => -1, - Ordering::Equal => 0, - Ordering::Greater => 1, - }, - ) + Ok(match Val::try_cmp(&v1, &v2)? { + Ordering::Less => -1, + Ordering::Equal => 0, + Ordering::Greater => 1, + }) } #[builtin] @@ -27,11 +23,7 @@ #[builtin] #[allow(non_snake_case)] pub fn $name(arr1: ArrValue, arr2: ArrValue) -> Result { - let ordering = evaluate_compare_op( - &Val::Arr(arr1), - &Val::Arr(arr2), - jrsonnet_ir::BinaryOpType::Lt, - )?; + let ordering = Val::try_cmp(&Val::Arr(arr1), &Val::Arr(arr2))?; Ok($operator.contains(&ordering)) } }; --- a/crates/jrsonnet-stdlib/src/operator.rs +++ b/crates/jrsonnet-stdlib/src/operator.rs @@ -2,18 +2,17 @@ //! However, in our case we instead implement them in native, and implement native functions on top of core for backwards compatibility use jrsonnet_evaluator::{ - IStr, NumValue, Result, Val, function::builtin, - operator::evaluate_mod_op, stdlib::std_format, typed::{Either, Either2}, val::{equals, primitive_equals}, + IStr, NumValue, Result, Val, }; #[builtin] pub fn builtin_mod(a: Either![NumValue, IStr], b: Val) -> Result { use Either2::*; - evaluate_mod_op( + Val::try_mod( &match a { A(v) => Val::Num(v), B(s) => Val::string(s), --- a/crates/jrsonnet-stdlib/src/sets.rs +++ b/crates/jrsonnet-stdlib/src/sets.rs @@ -1,9 +1,6 @@ use std::cmp::Ordering; -use jrsonnet_evaluator::{ - Result, Thunk, Val, function::builtin, operator::evaluate_compare_op, val::ArrValue, -}; -use jrsonnet_ir::BinaryOpType; +use jrsonnet_evaluator::{function::builtin, val::ArrValue, Result, Thunk, Val}; use crate::keyf::KeyF; @@ -16,9 +13,9 @@ let x = keyF.eval(x)?; while low < high { - let middle = usize::midpoint(high, low); + let middle = u32::midpoint(high, low); let comp = keyF.eval(arr.get_lazy(middle).expect("in bounds"))?; - match evaluate_compare_op(&comp, &x, BinaryOpType::Lt)? { + match Val::try_cmp(&comp, &x)? { Ordering::Less => low = middle + 1, Ordering::Equal => return Ok(true), Ordering::Greater => high = middle, @@ -46,7 +43,7 @@ let mut out = Vec::new(); while let (Some(ac), Some(bc)) = (&ak, &bk) { - match evaluate_compare_op(ac, bc, BinaryOpType::Lt)? { + match Val::try_cmp(ac, bc)? { Ordering::Less => { av = a.next(); ak = av.clone().map(keyF).transpose()?; @@ -86,7 +83,7 @@ let mut out = Vec::new(); while let (Some(ac), Some(bc)) = (&ak, &bk) { - match evaluate_compare_op(ac, bc, BinaryOpType::Lt)? { + match Val::try_cmp(ac, bc)? { Ordering::Less => { // In a, but not in b out.push(av.clone().expect("ak != None")); @@ -133,7 +130,7 @@ let mut out = Vec::new(); while let (Some(ac), Some(bc)) = (&ak, &bk) { - match evaluate_compare_op(ac, bc, BinaryOpType::Lt)? { + match Val::try_cmp(ac, bc)? { Ordering::Less => { out.push(av.clone().expect("ak != None")); av = a.next(); --- a/crates/jrsonnet-stdlib/src/sort.rs +++ b/crates/jrsonnet-stdlib/src/sort.rs @@ -3,12 +3,11 @@ use std::cmp::Ordering; use jrsonnet_evaluator::{ - Result, Thunk, Val, bail, + bail, function::builtin, - operator::evaluate_compare_op, - val::{ArrValue, equals}, + val::{equals, ArrValue}, + Result, Thunk, Val, }; -use jrsonnet_ir::BinaryOpType; use crate::{eval_on_empty, keyf::KeyF}; @@ -53,7 +52,7 @@ let mut err = None; // evaluate_compare_op will never return equal on types, which are different from // jsonnet perspective - values.sort_unstable_by(|a, b| match evaluate_compare_op(a, b, BinaryOpType::Lt) { + values.sort_unstable_by(|a, b| match Val::try_cmp(a, b) { Ok(ord) => ord, Err(e) if err.is_none() => { let _ = err.insert(e); @@ -71,7 +70,7 @@ fn sort_keyf(values: ArrValue, keyf: KeyF) -> Result>> { // Slow path, user provided key getter - let mut vk = Vec::with_capacity(values.len()); + let mut vk = Vec::with_capacity(values.len() as usize); for value in values.iter_lazy() { vk.push((value.clone(), keyf.eval(value)?)); } @@ -89,16 +88,14 @@ let mut err = None; // evaluate_compare_op will never return equal on types, which are different from // jsonnet perspective - vk.sort_by( - |(_a, ak), (_b, bk)| match evaluate_compare_op(ak, bk, BinaryOpType::Lt) { - Ok(ord) => ord, - Err(e) if err.is_none() => { - let _ = err.insert(e); - Ordering::Equal - } - Err(_) => Ordering::Equal, - }, - ); + vk.sort_by(|(_a, ak), (_b, bk)| match Val::try_cmp(ak, bk) { + Ok(ord) => ord, + Err(e) if err.is_none() => { + let _ = err.insert(e); + Ordering::Equal + } + Err(_) => Ordering::Equal, + }); if let Some(err) = err { return Err(err); } @@ -195,7 +192,7 @@ for item in iter { let cur = item?; let cur_key = keyf.eval(Thunk::evaluated(cur.clone()))?; - if evaluate_compare_op(&cur_key, &min_key, BinaryOpType::Lt)? == ordering { + if Val::try_cmp(&cur_key, &min_key)? == ordering { min = cur; min_key = cur_key; } --- a/crates/jrsonnet-stdlib/src/strings.rs +++ b/crates/jrsonnet-stdlib/src/strings.rs @@ -26,7 +26,7 @@ #[builtin] pub fn builtin_str_replace(str: String, from: IStr, to: IStr) -> Result { if from.is_empty() { - bail!("'from' string must not be zero length"); + bail!("`from` string must not be zero length"); } Ok(str.replace(&from as &str, &to as &str)) } -- gitstuff