1use std::cmp::Ordering;23use jrsonnet_evaluator::{4 function::{builtin, FuncVal},5 operator::evaluate_compare_op,6 val::ArrValue,7 Result, Thunk, Val,8};9use jrsonnet_parser::BinaryOpType;1011#[builtin]12#[allow(non_snake_case)]13pub fn builtin_set_member(x: Thunk<Val>, arr: ArrValue, keyF: Option<FuncVal>) -> Result<bool> {14 let mut low = 0;15 let mut high = arr.len();1617 let keyF = keyF18 .unwrap_or(FuncVal::Id)19 .into_native::<((Thunk<Val>,), Val)>();2021 let x = keyF(x)?;2223 while low < high {24 let middle = (high + low) / 2;25 let comp = keyF(arr.get_lazy(middle).expect("in bounds"))?;26 match evaluate_compare_op(&comp, &x, BinaryOpType::Lt)? {27 Ordering::Less => low = middle + 1,28 Ordering::Equal => return Ok(true),29 Ordering::Greater => high = middle,30 }31 }32 Ok(false)33}3435#[builtin]36#[allow(non_snake_case, clippy::redundant_closure)]37pub fn builtin_set_inter(a: ArrValue, b: ArrValue, keyF: Option<FuncVal>) -> Result<ArrValue> {38 let mut a = a.iter_lazy();39 let mut b = b.iter_lazy();4041 let keyF = keyF42 .unwrap_or(FuncVal::identity())43 .into_native::<((Thunk<Val>,), Val)>();44 let keyF = |v| keyF(v);4546 let mut av = a.next();47 let mut bv = b.next();48 let mut ak = av.clone().map(keyF).transpose()?;49 let mut bk = bv.map(keyF).transpose()?;5051 let mut out = Vec::new();52 while let (Some(ac), Some(bc)) = (&ak, &bk) {53 match evaluate_compare_op(ac, bc, BinaryOpType::Lt)? {54 Ordering::Less => {55 av = a.next();56 ak = av.clone().map(keyF).transpose()?;57 }58 Ordering::Greater => {59 bv = b.next();60 bk = bv.map(keyF).transpose()?;61 }62 Ordering::Equal => {63 out.push(av.clone().expect("ak != None => av != None"));64 av = a.next();65 ak = av.clone().map(keyF).transpose()?;66 bv = b.next();67 bk = bv.map(keyF).transpose()?;68 }69 };70 }71 Ok(ArrValue::lazy(out))72}73#[builtin]74#[allow(non_snake_case, clippy::redundant_closure)]75pub fn builtin_set_diff(a: ArrValue, b: ArrValue, keyF: Option<FuncVal>) -> Result<ArrValue> {76 let mut a = a.iter_lazy();77 let mut b = b.iter_lazy();7879 let keyF = keyF80 .unwrap_or(FuncVal::identity())81 .into_native::<((Thunk<Val>,), Val)>();82 let keyF = |v| keyF(v);8384 let mut av = a.next();85 let mut bv = b.next();86 let mut ak = av.clone().map(keyF).transpose()?;87 let mut bk = bv.map(keyF).transpose()?;8889 let mut out = Vec::new();90 while let (Some(ac), Some(bc)) = (&ak, &bk) {91 match evaluate_compare_op(ac, bc, BinaryOpType::Lt)? {92 Ordering::Less => {93 94 out.push(av.clone().expect("ak != None"));95 av = a.next();96 ak = av.clone().map(keyF).transpose()?;97 }98 Ordering::Greater => {99 bv = b.next();100 bk = bv.map(keyF).transpose()?;101 }102 Ordering::Equal => {103 av = a.next();104 ak = av.clone().map(keyF).transpose()?;105 bv = b.next();106 bk = bv.map(keyF).transpose()?;107 }108 };109 }110 while let Some(_ac) = &ak {111 112 out.push(av.clone().expect("ak != None"));113 av = a.next();114 ak = av.clone().map(keyF).transpose()?;115 }116 Ok(ArrValue::lazy(out))117}