1use std::collections::HashSet;
4
5use serde_json::{Number, Value};
6
7use crate::functions::{Function, custom_error};
8use crate::interpreter::SearchResult;
9use crate::registry::register_if_enabled;
10use crate::{Context, Runtime, arg, defn};
11
12pub fn register_filtered(runtime: &mut Runtime, enabled: &HashSet<&str>) {
14 register_if_enabled(runtime, "unique", enabled, Box::new(UniqueFn::new()));
15 register_if_enabled(runtime, "zip", enabled, Box::new(ZipFn::new()));
16 register_if_enabled(runtime, "chunk", enabled, Box::new(ChunkFn::new()));
17 register_if_enabled(runtime, "take", enabled, Box::new(TakeFn::new()));
18 register_if_enabled(runtime, "drop", enabled, Box::new(DropFn::new()));
19 register_if_enabled(
20 runtime,
21 "flatten_deep",
22 enabled,
23 Box::new(FlattenDeepFn::new()),
24 );
25 register_if_enabled(runtime, "flatten", enabled, Box::new(FlattenFn::new()));
26 register_if_enabled(runtime, "compact", enabled, Box::new(CompactFn::new()));
27 register_if_enabled(runtime, "range", enabled, Box::new(RangeFn::new()));
28 register_if_enabled(runtime, "index_at", enabled, Box::new(IndexAtFn::new()));
29 register_if_enabled(runtime, "includes", enabled, Box::new(IncludesFn::new()));
30 register_if_enabled(runtime, "find_index", enabled, Box::new(FindIndexFn::new()));
31 register_if_enabled(runtime, "first", enabled, Box::new(FirstFn::new()));
32 register_if_enabled(runtime, "last", enabled, Box::new(LastFn::new()));
33 register_if_enabled(runtime, "group_by", enabled, Box::new(GroupByFn::new()));
34 register_if_enabled(runtime, "index_by", enabled, Box::new(IndexByFn::new()));
35 register_if_enabled(runtime, "nth", enabled, Box::new(NthFn::new()));
36 register_if_enabled(
37 runtime,
38 "interleave",
39 enabled,
40 Box::new(InterleaveFn::new()),
41 );
42 register_if_enabled(runtime, "rotate", enabled, Box::new(RotateFn::new()));
43 register_if_enabled(runtime, "partition", enabled, Box::new(PartitionFn::new()));
44 register_if_enabled(
45 runtime,
46 "difference",
47 enabled,
48 Box::new(DifferenceFn::new()),
49 );
50 register_if_enabled(
51 runtime,
52 "intersection",
53 enabled,
54 Box::new(IntersectionFn::new()),
55 );
56 register_if_enabled(runtime, "union", enabled, Box::new(UnionFn::new()));
57 register_if_enabled(
58 runtime,
59 "frequencies",
60 enabled,
61 Box::new(FrequenciesFn::new()),
62 );
63 register_if_enabled(runtime, "mode", enabled, Box::new(ModeFn::new()));
64 register_if_enabled(runtime, "cartesian", enabled, Box::new(CartesianFn::new()));
65 register_if_enabled(runtime, "initial", enabled, Box::new(InitialFn::new()));
66 register_if_enabled(runtime, "butlast", enabled, Box::new(InitialFn::new()));
68 register_if_enabled(runtime, "interpose", enabled, Box::new(InterposeFn::new()));
70 register_if_enabled(runtime, "zipmap", enabled, Box::new(ZipmapFn::new()));
71 register_if_enabled(
72 runtime,
73 "partition_by",
74 enabled,
75 Box::new(PartitionByFn::new()),
76 );
77 register_if_enabled(runtime, "dedupe", enabled, Box::new(DedupeFn::new()));
78 register_if_enabled(runtime, "tail", enabled, Box::new(TailFn::new()));
79 register_if_enabled(runtime, "without", enabled, Box::new(WithoutFn::new()));
80 register_if_enabled(runtime, "xor", enabled, Box::new(XorFn::new()));
81 register_if_enabled(runtime, "fill", enabled, Box::new(FillFn::new()));
82 register_if_enabled(runtime, "pull_at", enabled, Box::new(PullAtFn::new()));
83 register_if_enabled(runtime, "window", enabled, Box::new(WindowFn::new()));
84 register_if_enabled(
85 runtime,
86 "combinations",
87 enabled,
88 Box::new(CombinationsFn::new()),
89 );
90 register_if_enabled(runtime, "transpose", enabled, Box::new(TransposeFn::new()));
91 register_if_enabled(runtime, "pairwise", enabled, Box::new(PairwiseFn::new()));
92 register_if_enabled(
94 runtime,
95 "sliding_window",
96 enabled,
97 Box::new(WindowFn::new()),
98 );
99 register_if_enabled(
101 runtime,
102 "indices_array",
103 enabled,
104 Box::new(IndicesArrayFn::new()),
105 );
106 register_if_enabled(
107 runtime,
108 "inside_array",
109 enabled,
110 Box::new(InsideArrayFn::new()),
111 );
112 register_if_enabled(runtime, "bsearch", enabled, Box::new(BsearchFn::new()));
113 register_if_enabled(
115 runtime,
116 "repeat_array",
117 enabled,
118 Box::new(RepeatArrayFn::new()),
119 );
120 register_if_enabled(runtime, "cycle", enabled, Box::new(CycleFn::new()));
121}
122
123defn!(UniqueFn, vec![arg!(array)], None);
128
129impl Function for UniqueFn {
130 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
131 self.signature.validate(args, ctx)?;
132
133 let arr = args[0]
134 .as_array()
135 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
136
137 let mut seen = HashSet::new();
138 let mut result = Vec::new();
139
140 for item in arr {
141 let key = serde_json::to_string(item).unwrap_or_default();
142 if seen.insert(key) {
143 result.push(item.clone());
144 }
145 }
146
147 Ok(Value::Array(result))
148 }
149}
150
151defn!(ZipFn, vec![arg!(array), arg!(array)], None);
156
157impl Function for ZipFn {
158 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
159 self.signature.validate(args, ctx)?;
160
161 let arr1 = args[0]
162 .as_array()
163 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
164
165 let arr2 = args[1]
166 .as_array()
167 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
168
169 let result: Vec<Value> = arr1
170 .iter()
171 .zip(arr2.iter())
172 .map(|(a, b)| Value::Array(vec![a.clone(), b.clone()]))
173 .collect();
174
175 Ok(Value::Array(result))
176 }
177}
178
179defn!(ChunkFn, vec![arg!(array), arg!(number)], None);
184
185impl Function for ChunkFn {
186 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
187 self.signature.validate(args, ctx)?;
188
189 let arr = args[0]
190 .as_array()
191 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
192
193 let size = args[1]
194 .as_f64()
195 .map(|n| n as usize)
196 .ok_or_else(|| custom_error(ctx, "Expected positive number for size"))?;
197
198 if size == 0 {
199 return Ok(Value::Array(vec![]));
200 }
201
202 let chunks: Vec<Value> = arr
203 .chunks(size)
204 .map(|chunk| Value::Array(chunk.to_vec()))
205 .collect();
206
207 Ok(Value::Array(chunks))
208 }
209}
210
211defn!(TakeFn, vec![arg!(array), arg!(number)], None);
216
217impl Function for TakeFn {
218 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
219 self.signature.validate(args, ctx)?;
220
221 let arr = args[0]
222 .as_array()
223 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
224
225 let n = args[1]
226 .as_f64()
227 .map(|n| n as usize)
228 .ok_or_else(|| custom_error(ctx, "Expected positive number"))?;
229
230 let result: Vec<Value> = arr.iter().take(n).cloned().collect();
231
232 Ok(Value::Array(result))
233 }
234}
235
236defn!(DropFn, vec![arg!(array), arg!(number)], None);
241
242impl Function for DropFn {
243 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
244 self.signature.validate(args, ctx)?;
245
246 let arr = args[0]
247 .as_array()
248 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
249
250 let n = args[1]
251 .as_f64()
252 .map(|n| n as usize)
253 .ok_or_else(|| custom_error(ctx, "Expected positive number"))?;
254
255 let result: Vec<Value> = arr.iter().skip(n).cloned().collect();
256
257 Ok(Value::Array(result))
258 }
259}
260
261defn!(FlattenDeepFn, vec![arg!(array)], None);
266
267fn flatten_recursive(arr: &[Value]) -> Vec<Value> {
268 let mut result = Vec::new();
269 for item in arr {
270 if let Some(inner) = item.as_array() {
271 result.extend(flatten_recursive(inner));
272 } else {
273 result.push(item.clone());
274 }
275 }
276 result
277}
278
279impl Function for FlattenDeepFn {
280 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
281 self.signature.validate(args, ctx)?;
282
283 let arr = args[0]
284 .as_array()
285 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
286
287 Ok(Value::Array(flatten_recursive(arr)))
288 }
289}
290
291defn!(FlattenFn, vec![arg!(array)], None);
296
297impl Function for FlattenFn {
298 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
299 self.signature.validate(args, ctx)?;
300
301 let arr = args[0]
302 .as_array()
303 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
304
305 let mut result = Vec::new();
306 for item in arr {
307 if let Some(inner) = item.as_array() {
308 result.extend(inner.iter().cloned());
309 } else {
310 result.push(item.clone());
311 }
312 }
313
314 Ok(Value::Array(result))
315 }
316}
317
318defn!(CompactFn, vec![arg!(array)], None);
323
324impl Function for CompactFn {
325 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
326 self.signature.validate(args, ctx)?;
327
328 let arr = args[0]
329 .as_array()
330 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
331
332 let result: Vec<Value> = arr
333 .iter()
334 .filter(|v| !v.is_null() && !matches!(v, Value::Bool(false)))
335 .cloned()
336 .collect();
337
338 Ok(Value::Array(result))
339 }
340}
341
342defn!(
347 RangeFn,
348 vec![arg!(number), arg!(number)],
349 Some(arg!(number))
350);
351
352impl Function for RangeFn {
353 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
354 self.signature.validate(args, ctx)?;
355
356 let start = args[0]
357 .as_f64()
358 .map(|n| n as i64)
359 .ok_or_else(|| custom_error(ctx, "Expected start number"))?;
360
361 let end = args[1]
362 .as_f64()
363 .map(|n| n as i64)
364 .ok_or_else(|| custom_error(ctx, "Expected end number"))?;
365
366 let step = if args.len() > 2 {
367 args[2]
368 .as_f64()
369 .map(|n| n as i64)
370 .ok_or_else(|| custom_error(ctx, "Expected step number"))?
371 } else {
372 1
373 };
374
375 if step == 0 {
376 return Err(custom_error(ctx, "Step cannot be zero"));
377 }
378
379 let mut result = Vec::new();
380 let mut current = start;
381
382 const MAX_RANGE: usize = 10000;
383
384 if step > 0 {
385 while current < end && result.len() < MAX_RANGE {
386 result.push(Value::Number(Number::from(current)));
387 current += step;
388 }
389 } else {
390 while current > end && result.len() < MAX_RANGE {
391 result.push(Value::Number(Number::from(current)));
392 current += step;
393 }
394 }
395
396 Ok(Value::Array(result))
397 }
398}
399
400defn!(IndexAtFn, vec![arg!(array), arg!(number)], None);
405
406impl Function for IndexAtFn {
407 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
408 self.signature.validate(args, ctx)?;
409
410 let arr = args[0]
411 .as_array()
412 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
413
414 let index = args[1]
415 .as_f64()
416 .map(|n| n as i64)
417 .ok_or_else(|| custom_error(ctx, "Expected number for index"))?;
418
419 let len = arr.len() as i64;
420 let actual_index = if index < 0 {
421 (len + index) as usize
422 } else {
423 index as usize
424 };
425
426 if actual_index < arr.len() {
427 Ok(arr[actual_index].clone())
428 } else {
429 Ok(Value::Null)
430 }
431 }
432}
433
434defn!(IncludesFn, vec![arg!(array), arg!(any)], None);
439
440impl Function for IncludesFn {
441 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
442 self.signature.validate(args, ctx)?;
443
444 let arr = args[0]
445 .as_array()
446 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
447
448 let search_key = serde_json::to_string(&args[1]).unwrap_or_default();
449
450 let found = arr.iter().any(|item| {
451 let item_key = serde_json::to_string(item).unwrap_or_default();
452 item_key == search_key
453 });
454
455 Ok(Value::Bool(found))
456 }
457}
458
459defn!(FindIndexFn, vec![arg!(array), arg!(any)], None);
464
465impl Function for FindIndexFn {
466 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
467 self.signature.validate(args, ctx)?;
468
469 let arr = args[0]
470 .as_array()
471 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
472
473 let search_key = serde_json::to_string(&args[1]).unwrap_or_default();
474
475 let index = arr
476 .iter()
477 .position(|item| {
478 let item_key = serde_json::to_string(item).unwrap_or_default();
479 item_key == search_key
480 })
481 .map(|i| i as i64)
482 .unwrap_or(-1);
483
484 Ok(Value::Number(Number::from(index)))
485 }
486}
487
488defn!(FirstFn, vec![arg!(array)], None);
493
494impl Function for FirstFn {
495 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
496 self.signature.validate(args, ctx)?;
497
498 let arr = args[0]
499 .as_array()
500 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
501
502 Ok(arr.first().cloned().unwrap_or(Value::Null))
503 }
504}
505
506defn!(LastFn, vec![arg!(array)], None);
511
512impl Function for LastFn {
513 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
514 self.signature.validate(args, ctx)?;
515
516 let arr = args[0]
517 .as_array()
518 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
519
520 Ok(arr.last().cloned().unwrap_or(Value::Null))
521 }
522}
523
524defn!(GroupByFn, vec![arg!(array), arg!(string)], None);
529
530impl Function for GroupByFn {
531 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
532 self.signature.validate(args, ctx)?;
533
534 let arr = args[0]
535 .as_array()
536 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
537
538 let field_name = args[1]
539 .as_str()
540 .ok_or_else(|| custom_error(ctx, "Expected field name string"))?;
541
542 let mut groups: std::collections::BTreeMap<String, Vec<Value>> =
543 std::collections::BTreeMap::new();
544
545 for item in arr {
546 let key = if let Some(obj) = item.as_object() {
547 if let Some(field_value) = obj.get(field_name) {
548 match field_value {
549 Value::String(s) => s.clone(),
550 Value::Number(n) => n.to_string(),
551 Value::Bool(b) => b.to_string(),
552 Value::Null => "null".to_string(),
553 _ => continue,
554 }
555 } else {
556 "null".to_string()
557 }
558 } else {
559 continue;
560 };
561 groups.entry(key).or_default().push(item.clone());
562 }
563
564 let mut result = serde_json::Map::new();
565 for (k, v) in groups {
566 result.insert(k, Value::Array(v));
567 }
568
569 Ok(Value::Object(result))
570 }
571}
572
573defn!(IndexByFn, vec![arg!(array), arg!(string)], None);
578
579impl Function for IndexByFn {
580 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
581 self.signature.validate(args, ctx)?;
582
583 let arr = args[0]
584 .as_array()
585 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
586
587 let field_name = args[1]
588 .as_str()
589 .ok_or_else(|| custom_error(ctx, "Expected field name string"))?;
590
591 let mut result = serde_json::Map::new();
592
593 for item in arr {
594 let key = if let Some(obj) = item.as_object() {
595 if let Some(field_value) = obj.get(field_name) {
596 match field_value {
597 Value::String(s) => s.clone(),
598 Value::Number(n) => n.to_string(),
599 Value::Bool(b) => b.to_string(),
600 Value::Null => "null".to_string(),
601 _ => continue,
602 }
603 } else {
604 continue;
606 }
607 } else {
608 continue;
609 };
610 result.insert(key, item.clone());
612 }
613
614 Ok(Value::Object(result))
615 }
616}
617
618defn!(NthFn, vec![arg!(array), arg!(number)], None);
623
624impl Function for NthFn {
625 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
626 self.signature.validate(args, ctx)?;
627
628 let arr = args[0]
629 .as_array()
630 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
631
632 let n = args[1]
633 .as_f64()
634 .ok_or_else(|| custom_error(ctx, "Expected number argument"))? as usize;
635
636 if n == 0 {
637 return Ok(Value::Null);
638 }
639
640 let result: Vec<Value> = arr.iter().step_by(n).cloned().collect();
641 Ok(Value::Array(result))
642 }
643}
644
645defn!(InterleaveFn, vec![arg!(array), arg!(array)], None);
650
651impl Function for InterleaveFn {
652 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
653 self.signature.validate(args, ctx)?;
654
655 let arr1 = args[0]
656 .as_array()
657 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
658
659 let arr2 = args[1]
660 .as_array()
661 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
662
663 let mut result = Vec::with_capacity(arr1.len() + arr2.len());
664 let mut iter1 = arr1.iter();
665 let mut iter2 = arr2.iter();
666
667 loop {
668 match (iter1.next(), iter2.next()) {
669 (Some(a), Some(b)) => {
670 result.push(a.clone());
671 result.push(b.clone());
672 }
673 (Some(a), None) => {
674 result.push(a.clone());
675 result.extend(iter1.cloned());
676 break;
677 }
678 (None, Some(b)) => {
679 result.push(b.clone());
680 result.extend(iter2.cloned());
681 break;
682 }
683 (None, None) => break,
684 }
685 }
686
687 Ok(Value::Array(result))
688 }
689}
690
691defn!(RotateFn, vec![arg!(array), arg!(number)], None);
696
697impl Function for RotateFn {
698 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
699 self.signature.validate(args, ctx)?;
700
701 let arr = args[0]
702 .as_array()
703 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
704
705 if arr.is_empty() {
706 return Ok(Value::Array(vec![]));
707 }
708
709 let n = args[1]
710 .as_f64()
711 .ok_or_else(|| custom_error(ctx, "Expected number argument"))? as i64;
712
713 let len = arr.len() as i64;
714 let rotation = ((n % len) + len) % len;
715 let rotation = rotation as usize;
716
717 let mut result = Vec::with_capacity(arr.len());
718 result.extend(arr[rotation..].iter().cloned());
719 result.extend(arr[..rotation].iter().cloned());
720
721 Ok(Value::Array(result))
722 }
723}
724
725defn!(PartitionFn, vec![arg!(array), arg!(number)], None);
730
731impl Function for PartitionFn {
732 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
733 self.signature.validate(args, ctx)?;
734
735 let arr = args[0]
736 .as_array()
737 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
738
739 let n = args[1]
740 .as_f64()
741 .ok_or_else(|| custom_error(ctx, "Expected number argument"))? as usize;
742
743 if n == 0 {
744 return Ok(Value::Null);
745 }
746
747 let len = arr.len();
748 let base_size = len / n;
749 let remainder = len % n;
750
751 let mut result = Vec::with_capacity(n);
752 let mut start = 0;
753
754 for i in 0..n {
755 let size = base_size + if i < remainder { 1 } else { 0 };
756 if size > 0 {
757 result.push(Value::Array(arr[start..start + size].to_vec()));
758 } else {
759 result.push(Value::Array(vec![]));
760 }
761 start += size;
762 }
763
764 Ok(Value::Array(result))
765 }
766}
767
768defn!(DifferenceFn, vec![arg!(array), arg!(array)], None);
773
774impl Function for DifferenceFn {
775 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
776 self.signature.validate(args, ctx)?;
777
778 let arr1 = args[0]
779 .as_array()
780 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
781
782 let arr2 = args[1]
783 .as_array()
784 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
785
786 let set2: HashSet<String> = arr2
787 .iter()
788 .map(|v| serde_json::to_string(v).unwrap_or_default())
789 .collect();
790
791 let result: Vec<Value> = arr1
792 .iter()
793 .filter(|v| {
794 let key = serde_json::to_string(*v).unwrap_or_default();
795 !set2.contains(&key)
796 })
797 .cloned()
798 .collect();
799
800 Ok(Value::Array(result))
801 }
802}
803
804defn!(IntersectionFn, vec![arg!(array), arg!(array)], None);
809
810impl Function for IntersectionFn {
811 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
812 self.signature.validate(args, ctx)?;
813
814 let arr1 = args[0]
815 .as_array()
816 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
817
818 let arr2 = args[1]
819 .as_array()
820 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
821
822 let set2: HashSet<String> = arr2
823 .iter()
824 .map(|v| serde_json::to_string(v).unwrap_or_default())
825 .collect();
826
827 let mut seen: HashSet<String> = HashSet::new();
828 let result: Vec<Value> = arr1
829 .iter()
830 .filter(|v| {
831 let key = serde_json::to_string(*v).unwrap_or_default();
832 set2.contains(&key) && seen.insert(key)
833 })
834 .cloned()
835 .collect();
836
837 Ok(Value::Array(result))
838 }
839}
840
841defn!(UnionFn, vec![arg!(array), arg!(array)], None);
846
847impl Function for UnionFn {
848 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
849 self.signature.validate(args, ctx)?;
850
851 let arr1 = args[0]
852 .as_array()
853 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
854
855 let arr2 = args[1]
856 .as_array()
857 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
858
859 let mut seen: HashSet<String> = HashSet::new();
860 let mut result: Vec<Value> = Vec::new();
861
862 for item in arr1.iter().chain(arr2.iter()) {
863 let key = serde_json::to_string(item).unwrap_or_default();
864 if seen.insert(key) {
865 result.push(item.clone());
866 }
867 }
868
869 Ok(Value::Array(result))
870 }
871}
872
873defn!(FrequenciesFn, vec![arg!(array)], None);
878
879impl Function for FrequenciesFn {
880 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
881 self.signature.validate(args, ctx)?;
882
883 let arr = args[0]
884 .as_array()
885 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
886
887 let mut counts: std::collections::HashMap<String, i64> = std::collections::HashMap::new();
888
889 for item in arr {
890 let key = match item {
891 Value::String(s) => s.clone(),
892 Value::Number(n) => n.to_string(),
893 Value::Bool(b) => b.to_string(),
894 Value::Null => "null".to_string(),
895 _ => serde_json::to_string(item).unwrap_or_else(|_| "null".to_string()),
896 };
897 *counts.entry(key).or_insert(0) += 1;
898 }
899
900 let mut result = serde_json::Map::new();
901 let sorted: std::collections::BTreeMap<String, i64> = counts.into_iter().collect();
903 for (k, v) in sorted {
904 result.insert(k, Value::Number(Number::from(v)));
905 }
906
907 Ok(Value::Object(result))
908 }
909}
910
911defn!(ModeFn, vec![arg!(array)], None);
916
917impl Function for ModeFn {
918 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
919 self.signature.validate(args, ctx)?;
920
921 let arr = args[0]
922 .as_array()
923 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
924
925 if arr.is_empty() {
926 return Ok(Value::Null);
927 }
928
929 let mut counts: std::collections::HashMap<String, (i64, Value)> =
930 std::collections::HashMap::new();
931
932 for item in arr {
933 let key = serde_json::to_string(item).unwrap_or_default();
934 counts
935 .entry(key)
936 .and_modify(|(count, _)| *count += 1)
937 .or_insert((1, item.clone()));
938 }
939
940 let (_, (_, mode_value)) = counts
941 .into_iter()
942 .max_by_key(|(_, (count, _))| *count)
943 .unwrap();
944
945 Ok(mode_value)
946 }
947}
948
949defn!(CartesianFn, vec![arg!(array)], Some(arg!(array)));
955
956impl Function for CartesianFn {
957 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
958 self.signature.validate(args, ctx)?;
959
960 let first = args[0]
961 .as_array()
962 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
963
964 if args.len() == 2 {
969 let arr2 = args[1]
971 .as_array()
972 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
973
974 let mut result = Vec::with_capacity(first.len() * arr2.len());
975 for a in first {
976 for b in arr2 {
977 result.push(Value::Array(vec![a.clone(), b.clone()]));
978 }
979 }
980 Ok(Value::Array(result))
981 } else {
982 let arrays: Vec<&Vec<Value>> =
985 first.iter().filter_map(|item| item.as_array()).collect();
986
987 if arrays.len() != first.len() || arrays.is_empty() {
988 return Ok(Value::Array(vec![]));
990 }
991
992 let result = cartesian_product_n(&arrays);
994 Ok(Value::Array(result))
995 }
996 }
997}
998
999fn cartesian_product_n(arrays: &[&Vec<Value>]) -> Vec<Value> {
1001 if arrays.is_empty() {
1002 return vec![];
1003 }
1004
1005 if arrays.len() == 1 {
1006 return arrays[0]
1008 .iter()
1009 .map(|item| Value::Array(vec![item.clone()]))
1010 .collect();
1011 }
1012
1013 let total_size: usize = arrays.iter().map(|a| a.len()).product();
1015 if total_size == 0 {
1016 return vec![];
1017 }
1018
1019 let mut result = Vec::with_capacity(total_size);
1020
1021 let mut indices = vec![0usize; arrays.len()];
1023
1024 loop {
1025 let combo: Vec<Value> = indices
1027 .iter()
1028 .enumerate()
1029 .map(|(arr_idx, &elem_idx)| arrays[arr_idx][elem_idx].clone())
1030 .collect();
1031 result.push(Value::Array(combo));
1032
1033 let mut carry = true;
1035 for i in (0..arrays.len()).rev() {
1036 if carry {
1037 indices[i] += 1;
1038 if indices[i] >= arrays[i].len() {
1039 indices[i] = 0;
1040 } else {
1041 carry = false;
1042 }
1043 }
1044 }
1045
1046 if carry {
1048 break;
1049 }
1050 }
1051
1052 result
1053}
1054
1055defn!(InitialFn, vec![arg!(array)], None);
1060
1061impl Function for InitialFn {
1062 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1063 self.signature.validate(args, ctx)?;
1064
1065 let arr = args[0]
1066 .as_array()
1067 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1068
1069 if arr.is_empty() {
1070 return Ok(Value::Array(vec![]));
1071 }
1072
1073 let result: Vec<Value> = arr[..arr.len() - 1].to_vec();
1074 Ok(Value::Array(result))
1075 }
1076}
1077
1078defn!(InterposeFn, vec![arg!(array), arg!(any)], None);
1083
1084impl Function for InterposeFn {
1085 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1086 self.signature.validate(args, ctx)?;
1087
1088 let arr = args[0]
1089 .as_array()
1090 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1091
1092 let separator = args[1].clone();
1093
1094 if arr.is_empty() {
1095 return Ok(Value::Array(vec![]));
1096 }
1097
1098 if arr.len() == 1 {
1099 return Ok(Value::Array(arr.clone()));
1100 }
1101
1102 let mut result = Vec::with_capacity(arr.len() * 2 - 1);
1103 for (i, item) in arr.iter().enumerate() {
1104 if i > 0 {
1105 result.push(separator.clone());
1106 }
1107 result.push(item.clone());
1108 }
1109
1110 Ok(Value::Array(result))
1111 }
1112}
1113
1114defn!(ZipmapFn, vec![arg!(array), arg!(array)], None);
1119
1120impl Function for ZipmapFn {
1121 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1122 self.signature.validate(args, ctx)?;
1123
1124 let keys = args[0]
1125 .as_array()
1126 .ok_or_else(|| custom_error(ctx, "Expected array argument for keys"))?;
1127
1128 let values = args[1]
1129 .as_array()
1130 .ok_or_else(|| custom_error(ctx, "Expected array argument for values"))?;
1131
1132 let len = keys.len().min(values.len());
1133 let mut result = serde_json::Map::new();
1134
1135 for i in 0..len {
1136 let key = keys[i]
1137 .as_str()
1138 .ok_or_else(|| custom_error(ctx, "Keys must be strings"))?;
1139 result.insert(key.to_string(), values[i].clone());
1140 }
1141
1142 Ok(Value::Object(result))
1143 }
1144}
1145
1146defn!(PartitionByFn, vec![arg!(array), arg!(string)], None);
1151
1152impl Function for PartitionByFn {
1153 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1154 self.signature.validate(args, ctx)?;
1155
1156 let arr = args[0]
1157 .as_array()
1158 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1159
1160 let field_name = args[1]
1161 .as_str()
1162 .ok_or_else(|| custom_error(ctx, "Expected field name string"))?;
1163
1164 if arr.is_empty() {
1165 return Ok(Value::Array(vec![]));
1166 }
1167
1168 let mut result: Vec<Value> = Vec::new();
1169 let mut current_partition: Vec<Value> = Vec::new();
1170 let mut last_key: Option<String> = None;
1171
1172 for item in arr {
1173 let key = if let Some(obj) = item.as_object() {
1175 if let Some(field_value) = obj.get(field_name) {
1176 serde_json::to_string(field_value).unwrap_or_default()
1177 } else {
1178 "null".to_string()
1179 }
1180 } else {
1181 serde_json::to_string(item).unwrap_or_default()
1183 };
1184
1185 match &last_key {
1186 Some(prev_key) if *prev_key == key => {
1187 current_partition.push(item.clone());
1188 }
1189 _ => {
1190 if !current_partition.is_empty() {
1191 result.push(Value::Array(current_partition));
1192 }
1193 current_partition = vec![item.clone()];
1194 last_key = Some(key);
1195 }
1196 }
1197 }
1198
1199 if !current_partition.is_empty() {
1201 result.push(Value::Array(current_partition));
1202 }
1203
1204 Ok(Value::Array(result))
1205 }
1206}
1207
1208defn!(DedupeFn, vec![arg!(array)], None);
1213
1214impl Function for DedupeFn {
1215 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1216 self.signature.validate(args, ctx)?;
1217
1218 let arr = args[0]
1219 .as_array()
1220 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1221
1222 if arr.is_empty() {
1223 return Ok(Value::Array(vec![]));
1224 }
1225
1226 let mut result: Vec<Value> = Vec::with_capacity(arr.len());
1227 let mut last_key: Option<String> = None;
1228
1229 for item in arr {
1230 let key = serde_json::to_string(item).unwrap_or_default();
1231 match &last_key {
1232 Some(prev_key) if *prev_key == key => {
1233 }
1235 _ => {
1236 result.push(item.clone());
1237 last_key = Some(key);
1238 }
1239 }
1240 }
1241
1242 Ok(Value::Array(result))
1243 }
1244}
1245
1246defn!(TailFn, vec![arg!(array)], None);
1251
1252impl Function for TailFn {
1253 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1254 self.signature.validate(args, ctx)?;
1255
1256 let arr = args[0]
1257 .as_array()
1258 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1259
1260 if arr.is_empty() {
1261 return Ok(Value::Array(vec![]));
1262 }
1263
1264 let result: Vec<Value> = arr[1..].to_vec();
1265 Ok(Value::Array(result))
1266 }
1267}
1268
1269defn!(WithoutFn, vec![arg!(array), arg!(array)], None);
1274
1275impl Function for WithoutFn {
1276 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1277 self.signature.validate(args, ctx)?;
1278
1279 let arr = args[0]
1280 .as_array()
1281 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1282
1283 let exclude = args[1]
1284 .as_array()
1285 .ok_or_else(|| custom_error(ctx, "Expected array argument for values to exclude"))?;
1286
1287 let exclude_set: HashSet<String> = exclude
1289 .iter()
1290 .map(|v| serde_json::to_string(v).unwrap_or_default())
1291 .collect();
1292
1293 let result: Vec<Value> = arr
1294 .iter()
1295 .filter(|item| {
1296 let key = serde_json::to_string(*item).unwrap_or_default();
1297 !exclude_set.contains(&key)
1298 })
1299 .cloned()
1300 .collect();
1301
1302 Ok(Value::Array(result))
1303 }
1304}
1305
1306defn!(XorFn, vec![arg!(array), arg!(array)], None);
1311
1312impl Function for XorFn {
1313 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1314 self.signature.validate(args, ctx)?;
1315
1316 let arr1 = args[0]
1317 .as_array()
1318 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1319
1320 let arr2 = args[1]
1321 .as_array()
1322 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1323
1324 let set1: HashSet<String> = arr1
1326 .iter()
1327 .map(|v| serde_json::to_string(v).unwrap_or_default())
1328 .collect();
1329
1330 let set2: HashSet<String> = arr2
1331 .iter()
1332 .map(|v| serde_json::to_string(v).unwrap_or_default())
1333 .collect();
1334
1335 let mut result = Vec::new();
1336
1337 for item in arr1 {
1339 let key = serde_json::to_string(item).unwrap_or_default();
1340 if !set2.contains(&key) {
1341 result.push(item.clone());
1342 }
1343 }
1344
1345 for item in arr2 {
1347 let key = serde_json::to_string(item).unwrap_or_default();
1348 if !set1.contains(&key) {
1349 result.push(item.clone());
1350 }
1351 }
1352
1353 Ok(Value::Array(result))
1354 }
1355}
1356
1357defn!(
1362 WindowFn,
1363 vec![arg!(array), arg!(number)],
1364 Some(arg!(number))
1365);
1366
1367impl Function for WindowFn {
1368 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1369 self.signature.validate(args, ctx)?;
1370
1371 let arr = args[0]
1372 .as_array()
1373 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1374
1375 let size = args[1]
1376 .as_f64()
1377 .ok_or_else(|| custom_error(ctx, "Expected number for window size"))?
1378 as usize;
1379
1380 if size == 0 {
1381 return Ok(Value::Array(vec![]));
1382 }
1383
1384 let step = if args.len() > 2 {
1386 args[2]
1387 .as_f64()
1388 .ok_or_else(|| custom_error(ctx, "Expected number for step"))? as usize
1389 } else {
1390 1
1391 };
1392
1393 if step == 0 {
1394 return Err(custom_error(ctx, "Step cannot be zero"));
1395 }
1396
1397 let len = arr.len();
1398 if len < size {
1399 return Ok(Value::Array(vec![]));
1400 }
1401
1402 let mut result = Vec::new();
1403 let mut i = 0;
1404
1405 while i + size <= len {
1406 let window: Vec<Value> = arr[i..i + size].to_vec();
1407 result.push(Value::Array(window));
1408 i += step;
1409 }
1410
1411 Ok(Value::Array(result))
1412 }
1413}
1414
1415defn!(CombinationsFn, vec![arg!(array), arg!(number)], None);
1420
1421fn generate_combinations(arr: &[Value], k: usize) -> Vec<Vec<Value>> {
1422 if k == 0 {
1423 return vec![vec![]];
1424 }
1425 if arr.len() < k {
1426 return vec![];
1427 }
1428
1429 let mut result = Vec::new();
1430
1431 let first = arr[0].clone();
1433 let rest = &arr[1..];
1434 for mut combo in generate_combinations(rest, k - 1) {
1435 let mut new_combo = vec![first.clone()];
1436 new_combo.append(&mut combo);
1437 result.push(new_combo);
1438 }
1439
1440 result.extend(generate_combinations(rest, k));
1442
1443 result
1444}
1445
1446impl Function for CombinationsFn {
1447 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1448 self.signature.validate(args, ctx)?;
1449
1450 let arr = args[0]
1451 .as_array()
1452 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1453
1454 let k = args[1]
1455 .as_f64()
1456 .ok_or_else(|| custom_error(ctx, "Expected number for k"))? as usize;
1457
1458 const MAX_COMBINATIONS: usize = 10000;
1460
1461 let n = arr.len();
1463 if n > 20 && k > 3 && k < n - 3 {
1464 return Err(custom_error(ctx, "Combination size too large"));
1465 }
1466
1467 let combinations = generate_combinations(arr, k);
1468
1469 if combinations.len() > MAX_COMBINATIONS {
1470 return Err(custom_error(ctx, "Too many combinations generated"));
1471 }
1472
1473 let result: Vec<Value> = combinations.into_iter().map(Value::Array).collect();
1474
1475 Ok(Value::Array(result))
1476 }
1477}
1478
1479defn!(FillFn, vec![arg!(array), arg!(any)], Some(arg!(number)));
1484
1485impl Function for FillFn {
1486 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1487 self.signature.validate(args, ctx)?;
1488
1489 let arr = args[0]
1490 .as_array()
1491 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1492
1493 let fill_value = args[1].clone();
1494
1495 let len = arr.len();
1496 if len == 0 {
1497 return Ok(Value::Array(vec![]));
1498 }
1499
1500 let start = if args.len() > 2 {
1502 let s = args[2]
1503 .as_f64()
1504 .ok_or_else(|| custom_error(ctx, "Expected number for start index"))?
1505 as i64;
1506 if s < 0 {
1508 (len as i64 + s).max(0) as usize
1509 } else {
1510 (s as usize).min(len)
1511 }
1512 } else {
1513 0
1514 };
1515
1516 let end = if args.len() > 3 {
1517 let e = args[3]
1518 .as_f64()
1519 .ok_or_else(|| custom_error(ctx, "Expected number for end index"))?
1520 as i64;
1521 if e < 0 {
1523 (len as i64 + e).max(0) as usize
1524 } else {
1525 (e as usize).min(len)
1526 }
1527 } else {
1528 len
1529 };
1530
1531 let mut result: Vec<Value> = arr.clone();
1532
1533 for item in result.iter_mut().take(end.min(len)).skip(start) {
1534 *item = fill_value.clone();
1535 }
1536
1537 Ok(Value::Array(result))
1538 }
1539}
1540
1541defn!(PullAtFn, vec![arg!(array), arg!(array)], None);
1546
1547impl Function for PullAtFn {
1548 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1549 self.signature.validate(args, ctx)?;
1550
1551 let arr = args[0]
1552 .as_array()
1553 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1554
1555 let indices = args[1]
1556 .as_array()
1557 .ok_or_else(|| custom_error(ctx, "Expected array of indices"))?;
1558
1559 let len = arr.len();
1560 let mut result = Vec::new();
1561
1562 for idx_var in indices {
1563 let idx = idx_var
1564 .as_f64()
1565 .ok_or_else(|| custom_error(ctx, "Expected number in indices array"))?
1566 as i64;
1567
1568 let actual_idx = if idx < 0 {
1570 (len as i64 + idx).max(0) as usize
1571 } else {
1572 idx as usize
1573 };
1574
1575 if actual_idx < len {
1576 result.push(arr[actual_idx].clone());
1577 }
1578 }
1579
1580 Ok(Value::Array(result))
1581 }
1582}
1583
1584defn!(TransposeFn, vec![arg!(array)], None);
1589
1590impl Function for TransposeFn {
1591 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1592 self.signature.validate(args, ctx)?;
1593
1594 let arr = args[0]
1595 .as_array()
1596 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1597
1598 if arr.is_empty() {
1599 return Ok(Value::Array(vec![]));
1600 }
1601
1602 let mut inner_arrays: Vec<&Vec<Value>> = Vec::new();
1604 let mut min_len = usize::MAX;
1605
1606 for item in arr {
1607 if let Some(inner) = item.as_array() {
1608 min_len = min_len.min(inner.len());
1609 inner_arrays.push(inner);
1610 } else {
1611 return Ok(Value::Array(vec![]));
1613 }
1614 }
1615
1616 if inner_arrays.is_empty() || min_len == 0 {
1617 return Ok(Value::Array(vec![]));
1618 }
1619
1620 let mut result = Vec::with_capacity(min_len);
1622 for i in 0..min_len {
1623 let mut row = Vec::with_capacity(inner_arrays.len());
1624 for inner in &inner_arrays {
1625 row.push(inner[i].clone());
1626 }
1627 result.push(Value::Array(row));
1628 }
1629
1630 Ok(Value::Array(result))
1631 }
1632}
1633
1634defn!(PairwiseFn, vec![arg!(array)], None);
1639
1640impl Function for PairwiseFn {
1641 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1642 self.signature.validate(args, ctx)?;
1643
1644 let arr = args[0]
1645 .as_array()
1646 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1647
1648 if arr.len() < 2 {
1649 return Ok(Value::Array(vec![]));
1650 }
1651
1652 let mut result = Vec::with_capacity(arr.len() - 1);
1653 for i in 0..arr.len() - 1 {
1654 let pair = vec![arr[i].clone(), arr[i + 1].clone()];
1655 result.push(Value::Array(pair));
1656 }
1657
1658 Ok(Value::Array(result))
1659 }
1660}
1661
1662defn!(IndicesArrayFn, vec![arg!(array), arg!(any)], None);
1667
1668impl Function for IndicesArrayFn {
1669 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1670 self.signature.validate(args, ctx)?;
1671
1672 let arr = args[0]
1673 .as_array()
1674 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1675
1676 let search_key = serde_json::to_string(&args[1]).unwrap_or_default();
1677
1678 let mut indices: Vec<Value> = Vec::new();
1679 for (i, item) in arr.iter().enumerate() {
1680 let item_key = serde_json::to_string(item).unwrap_or_default();
1681 if item_key == search_key {
1682 indices.push(Value::Number(Number::from(i as i64)));
1683 }
1684 }
1685
1686 Ok(Value::Array(indices))
1687 }
1688}
1689
1690defn!(InsideArrayFn, vec![arg!(array), arg!(array)], None);
1695
1696impl Function for InsideArrayFn {
1697 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1698 self.signature.validate(args, ctx)?;
1699
1700 let needle = args[0]
1701 .as_array()
1702 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1703
1704 let haystack = args[1]
1705 .as_array()
1706 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1707
1708 let haystack_set: HashSet<String> = haystack
1710 .iter()
1711 .map(|item| serde_json::to_string(item).unwrap_or_default())
1712 .collect();
1713
1714 let result = needle.iter().all(|item| {
1716 let item_key = serde_json::to_string(item).unwrap_or_default();
1717 haystack_set.contains(&item_key)
1718 });
1719
1720 Ok(Value::Bool(result))
1721 }
1722}
1723
1724defn!(BsearchFn, vec![arg!(array), arg!(any)], None);
1729
1730impl Function for BsearchFn {
1731 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1732 self.signature.validate(args, ctx)?;
1733
1734 let arr = args[0]
1735 .as_array()
1736 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1737
1738 let target = &args[1];
1739
1740 if arr.is_empty() {
1741 return Ok(Value::Number(Number::from(-1)));
1742 }
1743
1744 fn compare_values(a: &Value, b: &Value) -> std::cmp::Ordering {
1747 match (a, b) {
1748 (Value::Number(n1), Value::Number(n2)) => {
1750 let f1 = n1.as_f64().unwrap_or(0.0);
1751 let f2 = n2.as_f64().unwrap_or(0.0);
1752 f1.partial_cmp(&f2).unwrap_or(std::cmp::Ordering::Equal)
1753 }
1754 (Value::String(s1), Value::String(s2)) => s1.cmp(s2),
1756 (Value::Bool(b1), Value::Bool(b2)) => b1.cmp(b2),
1758 _ => {
1760 let s1 = serde_json::to_string(a).unwrap_or_default();
1761 let s2 = serde_json::to_string(b).unwrap_or_default();
1762 s1.cmp(&s2)
1763 }
1764 }
1765 }
1766
1767 let mut left = 0i64;
1768 let mut right = arr.len() as i64 - 1;
1769
1770 while left <= right {
1771 let mid = left + (right - left) / 2;
1772
1773 match compare_values(&arr[mid as usize], target) {
1774 std::cmp::Ordering::Equal => {
1775 return Ok(Value::Number(Number::from(mid)));
1776 }
1777 std::cmp::Ordering::Less => {
1778 left = mid + 1;
1779 }
1780 std::cmp::Ordering::Greater => {
1781 right = mid - 1;
1782 }
1783 }
1784 }
1785
1786 let result = -(left) - 1;
1789 Ok(Value::Number(Number::from(result)))
1790 }
1791}
1792
1793defn!(RepeatArrayFn, vec![arg!(any), arg!(number)], None);
1798
1799impl Function for RepeatArrayFn {
1800 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1801 self.signature.validate(args, ctx)?;
1802
1803 let value = &args[0];
1804 let n = args[1]
1805 .as_f64()
1806 .ok_or_else(|| custom_error(ctx, "Expected number for count argument"))?
1807 as i64;
1808
1809 if n < 0 {
1810 return Err(custom_error(ctx, "Count must be non-negative"));
1811 }
1812
1813 let result: Vec<Value> = (0..n).map(|_| value.clone()).collect();
1814 Ok(Value::Array(result))
1815 }
1816}
1817
1818defn!(CycleFn, vec![arg!(array), arg!(number)], None);
1823
1824impl Function for CycleFn {
1825 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1826 self.signature.validate(args, ctx)?;
1827
1828 let arr = args[0]
1829 .as_array()
1830 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1831
1832 let n = args[1]
1833 .as_f64()
1834 .ok_or_else(|| custom_error(ctx, "Expected number for count argument"))?
1835 as i64;
1836
1837 if n < 0 {
1838 return Err(custom_error(ctx, "Count must be non-negative"));
1839 }
1840
1841 if arr.is_empty() || n == 0 {
1842 return Ok(Value::Array(vec![]));
1843 }
1844
1845 let mut result: Vec<Value> = Vec::with_capacity(arr.len() * n as usize);
1846 for _ in 0..n {
1847 result.extend(arr.iter().cloned());
1848 }
1849 Ok(Value::Array(result))
1850 }
1851}