git.delta.rocks / jrsonnet / refs/commits / 54e5a6e38415

difftreelog

feat add std.minArray/std.maxArray

Yaroslav Bolyukin2023-06-14parent: #777cdf5.patch.diff
in: master
Upstream issue: https://github.com/google/jsonnet/pull/1081
Upstream issue: https://github.com/google/jsonnet/pull/1074

2 files changed

modifiedcrates/jrsonnet-stdlib/src/lib.rsdiffbeforeafterboth
112 ("sort", builtin_sort::INST),112 ("sort", builtin_sort::INST),
113 ("uniq", builtin_uniq::INST),113 ("uniq", builtin_uniq::INST),
114 ("set", builtin_set::INST),114 ("set", builtin_set::INST),
115 ("minArray", builtin_min_array::INST),
116 ("maxArray", builtin_max_array::INST),
115 // Hash117 // Hash
116 ("md5", builtin_md5::INST),118 ("md5", builtin_md5::INST),
117 ("sha256", builtin_sha256::INST),119 ("sha256", builtin_sha256::INST),
modifiedcrates/jrsonnet-stdlib/src/sort.rsdiffbeforeafterboth
1#![allow(non_snake_case)]
2
1use std::cmp::Ordering;3use std::cmp::Ordering;
24
9 Thunk, Val,11 Thunk, Val,
10};12};
11use jrsonnet_gcmodule::Cc;13use jrsonnet_gcmodule::Cc;
14use jrsonnet_parser::BinaryOpType;
1215
13#[derive(Copy, Clone)]16#[derive(Copy, Clone)]
14enum SortKeyType {17enum SortKeyType {
64 let mut err = None;67 let mut err = None;
65 // evaluate_compare_op will never return equal on types, which are different from68 // evaluate_compare_op will never return equal on types, which are different from
66 // jsonnet perspective69 // jsonnet perspective
67 values.sort_unstable_by(|a, b| {70 values.sort_unstable_by(|a, b| match evaluate_compare_op(a, b, BinaryOpType::Lt) {
68 match evaluate_compare_op(a, b, jrsonnet_parser::BinaryOpType::Lt) {
69 Ok(ord) => ord,71 Ok(ord) => ord,
70 Err(e) if err.is_none() => {72 Err(e) if err.is_none() => {
71 let _ = err.insert(e);73 let _ = err.insert(e);
72 Ordering::Equal74 Ordering::Equal
73 }75 }
74 Err(_) => Ordering::Equal,76 Err(_) => Ordering::Equal,
75 }77 });
76 });
77 if let Some(err) = err {78 if let Some(err) = err {
78 return Err(err);79 return Err(err);
79 }80 }
105 let mut err = None;106 let mut err = None;
106 // evaluate_compare_op will never return equal on types, which are different from107 // evaluate_compare_op will never return equal on types, which are different from
107 // jsonnet perspective108 // jsonnet perspective
108 vk.sort_by(|(_a, ak), (_b, bk)| {109 vk.sort_by(
109 match evaluate_compare_op(ak, bk, jrsonnet_parser::BinaryOpType::Lt) {110 |(_a, ak), (_b, bk)| match evaluate_compare_op(ak, bk, BinaryOpType::Lt) {
110 Ok(ord) => ord,111 Ok(ord) => ord,
111 Err(e) if err.is_none() => {112 Err(e) if err.is_none() => {
112 let _ = err.insert(e);113 let _ = err.insert(e);
113 Ordering::Equal114 Ordering::Equal
114 }115 }
115 Err(_) => Ordering::Equal,116 Err(_) => Ordering::Equal,
116 }117 },
117 });118 );
118 if let Some(err) = err {119 if let Some(err) = err {
119 return Err(err);120 return Err(err);
120 }121 }
138}139}
139140
140#[builtin]141#[builtin]
141#[allow(non_snake_case)]
142pub fn builtin_sort(arr: ArrValue, keyF: Option<FuncVal>) -> Result<ArrValue> {142pub fn builtin_sort(arr: ArrValue, keyF: Option<FuncVal>) -> Result<ArrValue> {
143 super::sort::sort(arr, keyF.unwrap_or_else(FuncVal::identity))143 super::sort::sort(arr, keyF.unwrap_or_else(FuncVal::identity))
144}144}
207 }207 }
208}208}
209
210fn eval_on_empty(on_empty: Option<Thunk<Val>>) -> Result<Val> {
211 if let Some(on_empty) = on_empty {
212 on_empty.evaluate()
213 } else {
214 throw!("expected non-empty array")
215 }
216}
217
218fn eval_keyf(val: Val, key_f: &Option<FuncVal>) -> Result<Val> {
219 if let Some(key_f) = key_f {
220 key_f.evaluate_simple(&(val,), false)
221 } else {
222 Ok(val)
223 }
224}
225
226fn array_top1(arr: ArrValue, key_f: Option<FuncVal>, ordering: Ordering) -> Result<Val> {
227 let mut iter = arr.iter();
228 let mut min = iter.next().expect("not empty")?;
229 let mut min_key = eval_keyf(min.clone(), &key_f)?;
230 for item in iter {
231 let cur = item?;
232 let cur_key = eval_keyf(cur.clone(), &key_f)?;
233 if evaluate_compare_op(&cur_key, &min_key, BinaryOpType::Lt)? == ordering {
234 min = cur;
235 min_key = cur_key;
236 }
237 }
238 Ok(min)
239}
240
241#[builtin]
242pub fn builtin_min_array(
243 arr: ArrValue,
244 keyF: Option<FuncVal>,
245 onEmpty: Option<Thunk<Val>>,
246) -> Result<Val> {
247 if arr.is_empty() {
248 return eval_on_empty(onEmpty);
249 }
250 array_top1(arr, keyF, Ordering::Less)
251}
252#[builtin]
253pub fn builtin_max_array(
254 arr: ArrValue,
255 keyF: Option<FuncVal>,
256 onEmpty: Option<Thunk<Val>>,
257) -> Result<Val> {
258 if arr.is_empty() {
259 return eval_on_empty(onEmpty);
260 }
261 array_top1(arr, keyF, Ordering::Greater)
262}
209263