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

difftreelog

refactor do not expose direct operator evaluator access

rkvzpxtpYaroslav Bolyukin2026-04-25parent: #c420c56.patch.diff
in: master

7 files changed

modifiedcrates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth
1010
11use jrsonnet_gcmodule::{Acyclic, Cc, Trace, cc_dyn};11use jrsonnet_gcmodule::{Acyclic, Cc, Trace, cc_dyn};
12use jrsonnet_interner::IStr;12use jrsonnet_interner::IStr;
13use jrsonnet_ir::BinaryOpType;
13pub use jrsonnet_macros::Thunk;14pub use jrsonnet_macros::Thunk;
14use jrsonnet_types::ValType;15use jrsonnet_types::ValType;
15use rustc_hash::FxHashMap;16use rustc_hash::FxHashMap;
1617
17pub use crate::arr::{ArrValue, ArrayLike};18pub use crate::arr::{ArrValue, ArrayLike};
18use crate::{19use crate::{
19 NumValue, ObjValue, Result, SupThis, Unbound, WeakSupThis, bail,20 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
20 error::{Error, ErrorKind::*},
21 function::FuncVal,
22 gc::WithCapacityExt as _,
23 manifest::{ManifestFormat, ToStringFormat},
24 typed::BoundedUsize,
25};21};
2622
27pub trait ThunkValue: Trace {23pub trait ThunkValue: Trace {
586 Self::Arr(ArrValue::new(a))582 Self::Arr(ArrValue::new(a))
587 }583 }
584
585 pub fn try_cmp(a: &Val, b: &Val) -> Result<Ordering> {
586 evaluate_compare_op(a, b, BinaryOpType::Lt)
587 }
588 pub fn try_mod(a: &Val, b: &Val) -> Result<Val> {
589 evaluate_mod_op(a, b)
590 }
588}591}
589592
590impl From<IStr> for Val {593impl From<IStr> for Val {
modifiedcrates/jrsonnet-stdlib/Cargo.tomldiffbeforeafterboth
17exp-bigint = ["dep:num-bigint", "jrsonnet-evaluator/exp-bigint"]17exp-bigint = ["dep:num-bigint", "jrsonnet-evaluator/exp-bigint"]
1818
19exp-null-coaelse = [19exp-null-coaelse = ["jrsonnet-evaluator/exp-null-coaelse"]
20 "jrsonnet-ir/exp-null-coaelse",
21 "jrsonnet-evaluator/exp-null-coaelse",
22]
23# std.regexMatch and other helpers20# std.regexMatch and other helpers
24exp-regex = ["dep:regex", "dep:lru", "dep:rustc-hash"]21exp-regex = ["dep:regex", "dep:lru", "dep:rustc-hash"]
2522
26[dependencies]23[dependencies]
27jrsonnet-evaluator.workspace = true24jrsonnet-evaluator.workspace = true
28jrsonnet-macros.workspace = true25jrsonnet-macros.workspace = true
29jrsonnet-ir.workspace = true
30jrsonnet-gcmodule.workspace = true26jrsonnet-gcmodule.workspace = true
3127
32# Used for std.parseJson/std.parseYaml28# Used for std.parseJson/std.parseYaml
modifiedcrates/jrsonnet-stdlib/src/compat.rsdiffbeforeafterboth
1use std::cmp::Ordering;1use std::cmp::Ordering;
22
3use jrsonnet_evaluator::{3use jrsonnet_evaluator::{function::builtin, val::ArrValue, Result, Val};
4 Result, Val, function::builtin, operator::evaluate_compare_op, val::ArrValue,
5};
64
7#[builtin]5#[builtin]
8#[allow(non_snake_case)]6#[allow(non_snake_case)]
9pub fn builtin___compare(v1: Val, v2: Val) -> Result<i32> {7pub fn builtin___compare(v1: Val, v2: Val) -> Result<i32> {
10 Ok(8 Ok(match Val::try_cmp(&v1, &v2)? {
11 match evaluate_compare_op(&v1, &v2, jrsonnet_ir::BinaryOpType::Lt)? {
12 Ordering::Less => -1,9 Ordering::Less => -1,
13 Ordering::Equal => 0,10 Ordering::Equal => 0,
14 Ordering::Greater => 1,11 Ordering::Greater => 1,
27 #[builtin]23 #[builtin]
28 #[allow(non_snake_case)]24 #[allow(non_snake_case)]
29 pub fn $name(arr1: ArrValue, arr2: ArrValue) -> Result<bool> {25 pub fn $name(arr1: ArrValue, arr2: ArrValue) -> Result<bool> {
30 let ordering = evaluate_compare_op(26 let ordering = Val::try_cmp(&Val::Arr(arr1), &Val::Arr(arr2))?;
31 &Val::Arr(arr1),
32 &Val::Arr(arr2),
33 jrsonnet_ir::BinaryOpType::Lt,
34 )?;
35 Ok($operator.contains(&ordering))27 Ok($operator.contains(&ordering))
36 }28 }
modifiedcrates/jrsonnet-stdlib/src/operator.rsdiffbeforeafterboth
2//! However, in our case we instead implement them in native, and implement native functions on top of core for backwards compatibility2//! However, in our case we instead implement them in native, and implement native functions on top of core for backwards compatibility
33
4use jrsonnet_evaluator::{4use jrsonnet_evaluator::{
5 IStr, NumValue, Result, Val,
6 function::builtin,5 function::builtin,
7 operator::evaluate_mod_op,
8 stdlib::std_format,6 stdlib::std_format,
9 typed::{Either, Either2},7 typed::{Either, Either2},
10 val::{equals, primitive_equals},8 val::{equals, primitive_equals},
9 IStr, NumValue, Result, Val,
11};10};
1211
13#[builtin]12#[builtin]
14pub fn builtin_mod(a: Either![NumValue, IStr], b: Val) -> Result<Val> {13pub fn builtin_mod(a: Either![NumValue, IStr], b: Val) -> Result<Val> {
15 use Either2::*;14 use Either2::*;
16 evaluate_mod_op(15 Val::try_mod(
17 &match a {16 &match a {
18 A(v) => Val::Num(v),17 A(v) => Val::Num(v),
19 B(s) => Val::string(s),18 B(s) => Val::string(s),
modifiedcrates/jrsonnet-stdlib/src/sets.rsdiffbeforeafterboth
1use std::cmp::Ordering;1use std::cmp::Ordering;
22
3use jrsonnet_evaluator::{3use jrsonnet_evaluator::{function::builtin, val::ArrValue, Result, Thunk, Val};
4 Result, Thunk, Val, function::builtin, operator::evaluate_compare_op, val::ArrValue,
5};
6use jrsonnet_ir::BinaryOpType;
74
8use crate::keyf::KeyF;5use crate::keyf::KeyF;
96
16 let x = keyF.eval(x)?;13 let x = keyF.eval(x)?;
1714
18 while low < high {15 while low < high {
19 let middle = usize::midpoint(high, low);16 let middle = u32::midpoint(high, low);
20 let comp = keyF.eval(arr.get_lazy(middle).expect("in bounds"))?;17 let comp = keyF.eval(arr.get_lazy(middle).expect("in bounds"))?;
21 match evaluate_compare_op(&comp, &x, BinaryOpType::Lt)? {18 match Val::try_cmp(&comp, &x)? {
22 Ordering::Less => low = middle + 1,19 Ordering::Less => low = middle + 1,
23 Ordering::Equal => return Ok(true),20 Ordering::Equal => return Ok(true),
24 Ordering::Greater => high = middle,21 Ordering::Greater => high = middle,
4643
47 let mut out = Vec::new();44 let mut out = Vec::new();
48 while let (Some(ac), Some(bc)) = (&ak, &bk) {45 while let (Some(ac), Some(bc)) = (&ak, &bk) {
49 match evaluate_compare_op(ac, bc, BinaryOpType::Lt)? {46 match Val::try_cmp(ac, bc)? {
50 Ordering::Less => {47 Ordering::Less => {
51 av = a.next();48 av = a.next();
52 ak = av.clone().map(keyF).transpose()?;49 ak = av.clone().map(keyF).transpose()?;
8683
87 let mut out = Vec::new();84 let mut out = Vec::new();
88 while let (Some(ac), Some(bc)) = (&ak, &bk) {85 while let (Some(ac), Some(bc)) = (&ak, &bk) {
89 match evaluate_compare_op(ac, bc, BinaryOpType::Lt)? {86 match Val::try_cmp(ac, bc)? {
90 Ordering::Less => {87 Ordering::Less => {
91 // In a, but not in b88 // In a, but not in b
92 out.push(av.clone().expect("ak != None"));89 out.push(av.clone().expect("ak != None"));
133130
134 let mut out = Vec::new();131 let mut out = Vec::new();
135 while let (Some(ac), Some(bc)) = (&ak, &bk) {132 while let (Some(ac), Some(bc)) = (&ak, &bk) {
136 match evaluate_compare_op(ac, bc, BinaryOpType::Lt)? {133 match Val::try_cmp(ac, bc)? {
137 Ordering::Less => {134 Ordering::Less => {
138 out.push(av.clone().expect("ak != None"));135 out.push(av.clone().expect("ak != None"));
139 av = a.next();136 av = a.next();
modifiedcrates/jrsonnet-stdlib/src/sort.rsdiffbeforeafterboth
3use std::cmp::Ordering;3use std::cmp::Ordering;
44
5use jrsonnet_evaluator::{5use jrsonnet_evaluator::{
6 Result, Thunk, Val, bail,6 bail,
7 function::builtin,7 function::builtin,
8 operator::evaluate_compare_op,
9 val::{ArrValue, equals},8 val::{equals, ArrValue},
9 Result, Thunk, Val,
10};10};
11use jrsonnet_ir::BinaryOpType;
1211
13use crate::{eval_on_empty, keyf::KeyF};12use crate::{eval_on_empty, keyf::KeyF};
1413
53 let mut err = None;52 let mut err = None;
54 // evaluate_compare_op will never return equal on types, which are different from53 // evaluate_compare_op will never return equal on types, which are different from
55 // jsonnet perspective54 // jsonnet perspective
56 values.sort_unstable_by(|a, b| match evaluate_compare_op(a, b, BinaryOpType::Lt) {55 values.sort_unstable_by(|a, b| match Val::try_cmp(a, b) {
57 Ok(ord) => ord,56 Ok(ord) => ord,
58 Err(e) if err.is_none() => {57 Err(e) if err.is_none() => {
59 let _ = err.insert(e);58 let _ = err.insert(e);
7170
72fn sort_keyf(values: ArrValue, keyf: KeyF) -> Result<Vec<Thunk<Val>>> {71fn sort_keyf(values: ArrValue, keyf: KeyF) -> Result<Vec<Thunk<Val>>> {
73 // Slow path, user provided key getter72 // Slow path, user provided key getter
74 let mut vk = Vec::with_capacity(values.len());73 let mut vk = Vec::with_capacity(values.len() as usize);
75 for value in values.iter_lazy() {74 for value in values.iter_lazy() {
76 vk.push((value.clone(), keyf.eval(value)?));75 vk.push((value.clone(), keyf.eval(value)?));
77 }76 }
89 let mut err = None;88 let mut err = None;
90 // evaluate_compare_op will never return equal on types, which are different from89 // evaluate_compare_op will never return equal on types, which are different from
91 // jsonnet perspective90 // jsonnet perspective
92 vk.sort_by(91 vk.sort_by(|(_a, ak), (_b, bk)| match Val::try_cmp(ak, bk) {
93 |(_a, ak), (_b, bk)| match evaluate_compare_op(ak, bk, BinaryOpType::Lt) {
94 Ok(ord) => ord,92 Ok(ord) => ord,
95 Err(e) if err.is_none() => {93 Err(e) if err.is_none() => {
96 let _ = err.insert(e);94 let _ = err.insert(e);
195 for item in iter {192 for item in iter {
196 let cur = item?;193 let cur = item?;
197 let cur_key = keyf.eval(Thunk::evaluated(cur.clone()))?;194 let cur_key = keyf.eval(Thunk::evaluated(cur.clone()))?;
198 if evaluate_compare_op(&cur_key, &min_key, BinaryOpType::Lt)? == ordering {195 if Val::try_cmp(&cur_key, &min_key)? == ordering {
199 min = cur;196 min = cur;
200 min_key = cur_key;197 min_key = cur_key;
201 }198 }
modifiedcrates/jrsonnet-stdlib/src/strings.rsdiffbeforeafterboth
26#[builtin]26#[builtin]
27pub fn builtin_str_replace(str: String, from: IStr, to: IStr) -> Result<String> {27pub fn builtin_str_replace(str: String, from: IStr, to: IStr) -> Result<String> {
28 if from.is_empty() {28 if from.is_empty() {
29 bail!("'from' string must not be zero length");29 bail!("`from` string must not be zero length");
30 }30 }
31 Ok(str.replace(&from as &str, &to as &str))31 Ok(str.replace(&from as &str, &to as &str))
32}32}