difftreelog
feat add std.minArray/std.maxArray
in: master
Upstream issue: https://github.com/google/jsonnet/pull/1081 Upstream issue: https://github.com/google/jsonnet/pull/1074
2 files changed
crates/jrsonnet-stdlib/src/lib.rsdiffbeforeafterboth112 ("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 // Hash116 ("md5", builtin_md5::INST),118 ("md5", builtin_md5::INST),117 ("sha256", builtin_sha256::INST),119 ("sha256", builtin_sha256::INST),crates/jrsonnet-stdlib/src/sort.rsdiffbeforeafterboth1#![allow(non_snake_case)]21use std::cmp::Ordering;3use std::cmp::Ordering;249 Thunk, Val,11 Thunk, Val,10};12};11use jrsonnet_gcmodule::Cc;13use jrsonnet_gcmodule::Cc;14use jrsonnet_parser::BinaryOpType;121513#[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 from66 // jsonnet perspective69 // jsonnet perspective67 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::Equal73 }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 from107 // jsonnet perspective108 // jsonnet perspective108 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::Equal114 }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}139140140#[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}209210fn 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}217218fn 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}225226fn 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}240241#[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