1use std::cmp::Ordering;23use jrsonnet_evaluator::{4 function::builtin, operator::evaluate_compare_op, val::ArrValue, Result, Thunk, Val,5};6use jrsonnet_parser::BinaryOpType;78use crate::keyf::KeyF;910#[builtin]11#[allow(non_snake_case)]12pub fn builtin_set_member(x: Thunk<Val>, arr: ArrValue, #[default] keyF: KeyF) -> Result<bool> {13 let mut low = 0;14 let mut high = arr.len();1516 let x = keyF.eval(x)?;1718 while low < high {19 let middle = usize::midpoint(high, low);20 let comp = keyF.eval(arr.get_lazy(middle).expect("in bounds"))?;21 match evaluate_compare_op(&comp, &x, BinaryOpType::Lt)? {22 Ordering::Less => low = middle + 1,23 Ordering::Equal => return Ok(true),24 Ordering::Greater => high = middle,25 }26 }27 Ok(false)28}2930#[builtin]31#[allow(non_snake_case, clippy::redundant_closure)]32pub fn builtin_set_inter(a: ArrValue, b: ArrValue, #[default] keyF: KeyF) -> Result<ArrValue> {33 let mut a = a.iter_lazy();34 let mut b = b.iter_lazy();3536 let keyF = |v| keyF.eval(v);3738 let mut av = a.next();39 let mut bv = b.next();40 let mut ak = av.clone().map(keyF).transpose()?;41 let mut bk = bv.map(keyF).transpose()?;4243 let mut out = Vec::new();44 while let (Some(ac), Some(bc)) = (&ak, &bk) {45 match evaluate_compare_op(ac, bc, BinaryOpType::Lt)? {46 Ordering::Less => {47 av = a.next();48 ak = av.clone().map(keyF).transpose()?;49 }50 Ordering::Greater => {51 bv = b.next();52 bk = bv.map(keyF).transpose()?;53 }54 Ordering::Equal => {55 out.push(av.clone().expect("ak != None => av != None"));56 av = a.next();57 ak = av.clone().map(keyF).transpose()?;58 bv = b.next();59 bk = bv.map(keyF).transpose()?;60 }61 }62 }63 Ok(ArrValue::lazy(out))64}6566#[builtin]67#[allow(non_snake_case, clippy::redundant_closure)]68pub fn builtin_set_diff(a: ArrValue, b: ArrValue, #[default] keyF: KeyF) -> Result<ArrValue> {69 let mut a = a.iter_lazy();70 let mut b = b.iter_lazy();7172 let keyF = |v| keyF.eval(v);7374 let mut av = a.next();75 let mut bv = b.next();76 let mut ak = av.clone().map(keyF).transpose()?;77 let mut bk = bv.map(keyF).transpose()?;7879 let mut out = Vec::new();80 while let (Some(ac), Some(bc)) = (&ak, &bk) {81 match evaluate_compare_op(ac, bc, BinaryOpType::Lt)? {82 Ordering::Less => {83 84 out.push(av.clone().expect("ak != None"));85 av = a.next();86 ak = av.clone().map(keyF).transpose()?;87 }88 Ordering::Greater => {89 bv = b.next();90 bk = bv.map(keyF).transpose()?;91 }92 Ordering::Equal => {93 av = a.next();94 ak = av.clone().map(keyF).transpose()?;95 bv = b.next();96 bk = bv.map(keyF).transpose()?;97 }98 }99 }100 while let Some(_ac) = &ak {101 102 out.push(av.clone().expect("ak != None"));103 av = a.next();104 ak = av.clone().map(keyF).transpose()?;105 }106 Ok(ArrValue::lazy(out))107}108109#[builtin]110#[allow(non_snake_case, clippy::redundant_closure)]111pub fn builtin_set_union(a: ArrValue, b: ArrValue, #[default] keyF: KeyF) -> Result<ArrValue> {112 let mut a = a.iter_lazy();113 let mut b = b.iter_lazy();114115 let keyF = |v| keyF.eval(v);116117 let mut av = a.next();118 let mut bv = b.next();119 let mut ak = av.clone().map(keyF).transpose()?;120 let mut bk = bv.clone().map(keyF).transpose()?;121122 let mut out = Vec::new();123 while let (Some(ac), Some(bc)) = (&ak, &bk) {124 match evaluate_compare_op(ac, bc, BinaryOpType::Lt)? {125 Ordering::Less => {126 out.push(av.clone().expect("ak != None"));127 av = a.next();128 ak = av.clone().map(keyF).transpose()?;129 }130 Ordering::Greater => {131 out.push(bv.clone().expect("bk != None"));132 bv = b.next();133 bk = bv.clone().map(keyF).transpose()?;134 }135 Ordering::Equal => {136 137 out.push(av.clone().expect("ak != None"));138 av = a.next();139 ak = av.clone().map(keyF).transpose()?;140 bv = b.next();141 bk = bv.clone().map(keyF).transpose()?;142 }143 }144 }145 146 while let Some(_ac) = &ak {147 out.push(av.clone().expect("ak != None"));148 av = a.next();149 ak = av.clone().map(keyF).transpose()?;150 }151 152 while let Some(_bc) = &bk {153 out.push(bv.clone().expect("ak != None"));154 bv = b.next();155 bk = bv.clone().map(keyF).transpose()?;156 }157 Ok(ArrValue::lazy(out))158}