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 register_if_enabled(runtime, "lag", enabled, Box::new(LagFn::new()));
122 register_if_enabled(runtime, "lead", enabled, Box::new(LeadFn::new()));
123}
124
125defn!(UniqueFn, vec![arg!(array)], None);
130
131impl Function for UniqueFn {
132 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
133 self.signature.validate(args, ctx)?;
134
135 let arr = args[0]
136 .as_array()
137 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
138
139 let mut seen = HashSet::new();
140 let mut result = Vec::new();
141
142 for item in arr {
143 let key = serde_json::to_string(item).unwrap_or_default();
144 if seen.insert(key) {
145 result.push(item.clone());
146 }
147 }
148
149 Ok(Value::Array(result))
150 }
151}
152
153defn!(ZipFn, vec![arg!(array), arg!(array)], None);
158
159impl Function for ZipFn {
160 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
161 self.signature.validate(args, ctx)?;
162
163 let arr1 = args[0]
164 .as_array()
165 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
166
167 let arr2 = args[1]
168 .as_array()
169 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
170
171 let result: Vec<Value> = arr1
172 .iter()
173 .zip(arr2.iter())
174 .map(|(a, b)| Value::Array(vec![a.clone(), b.clone()]))
175 .collect();
176
177 Ok(Value::Array(result))
178 }
179}
180
181defn!(ChunkFn, vec![arg!(array), arg!(number)], None);
186
187impl Function for ChunkFn {
188 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
189 self.signature.validate(args, ctx)?;
190
191 let arr = args[0]
192 .as_array()
193 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
194
195 let size = args[1]
196 .as_f64()
197 .map(|n| n as usize)
198 .ok_or_else(|| custom_error(ctx, "Expected positive number for size"))?;
199
200 if size == 0 {
201 return Ok(Value::Array(vec![]));
202 }
203
204 let chunks: Vec<Value> = arr
205 .chunks(size)
206 .map(|chunk| Value::Array(chunk.to_vec()))
207 .collect();
208
209 Ok(Value::Array(chunks))
210 }
211}
212
213defn!(TakeFn, vec![arg!(array), arg!(number)], None);
218
219impl Function for TakeFn {
220 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
221 self.signature.validate(args, ctx)?;
222
223 let arr = args[0]
224 .as_array()
225 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
226
227 let n = args[1]
228 .as_f64()
229 .map(|n| n as usize)
230 .ok_or_else(|| custom_error(ctx, "Expected positive number"))?;
231
232 let result: Vec<Value> = arr.iter().take(n).cloned().collect();
233
234 Ok(Value::Array(result))
235 }
236}
237
238defn!(DropFn, vec![arg!(array), arg!(number)], None);
243
244impl Function for DropFn {
245 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
246 self.signature.validate(args, ctx)?;
247
248 let arr = args[0]
249 .as_array()
250 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
251
252 let n = args[1]
253 .as_f64()
254 .map(|n| n as usize)
255 .ok_or_else(|| custom_error(ctx, "Expected positive number"))?;
256
257 let result: Vec<Value> = arr.iter().skip(n).cloned().collect();
258
259 Ok(Value::Array(result))
260 }
261}
262
263defn!(FlattenDeepFn, vec![arg!(array)], None);
268
269fn flatten_recursive(arr: &[Value]) -> Vec<Value> {
270 let mut result = Vec::new();
271 for item in arr {
272 if let Some(inner) = item.as_array() {
273 result.extend(flatten_recursive(inner));
274 } else {
275 result.push(item.clone());
276 }
277 }
278 result
279}
280
281impl Function for FlattenDeepFn {
282 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
283 self.signature.validate(args, ctx)?;
284
285 let arr = args[0]
286 .as_array()
287 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
288
289 Ok(Value::Array(flatten_recursive(arr)))
290 }
291}
292
293defn!(FlattenFn, vec![arg!(array)], None);
298
299impl Function for FlattenFn {
300 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
301 self.signature.validate(args, ctx)?;
302
303 let arr = args[0]
304 .as_array()
305 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
306
307 let mut result = Vec::new();
308 for item in arr {
309 if let Some(inner) = item.as_array() {
310 result.extend(inner.iter().cloned());
311 } else {
312 result.push(item.clone());
313 }
314 }
315
316 Ok(Value::Array(result))
317 }
318}
319
320defn!(CompactFn, vec![arg!(array)], None);
325
326impl Function for CompactFn {
327 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
328 self.signature.validate(args, ctx)?;
329
330 let arr = args[0]
331 .as_array()
332 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
333
334 let result: Vec<Value> = arr
335 .iter()
336 .filter(|v| !v.is_null() && !matches!(v, Value::Bool(false)))
337 .cloned()
338 .collect();
339
340 Ok(Value::Array(result))
341 }
342}
343
344defn!(
349 RangeFn,
350 vec![arg!(number), arg!(number)],
351 Some(arg!(number))
352);
353
354impl Function for RangeFn {
355 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
356 self.signature.validate(args, ctx)?;
357
358 let start = args[0]
359 .as_f64()
360 .map(|n| n as i64)
361 .ok_or_else(|| custom_error(ctx, "Expected start number"))?;
362
363 let end = args[1]
364 .as_f64()
365 .map(|n| n as i64)
366 .ok_or_else(|| custom_error(ctx, "Expected end number"))?;
367
368 let step = if args.len() > 2 {
369 args[2]
370 .as_f64()
371 .map(|n| n as i64)
372 .ok_or_else(|| custom_error(ctx, "Expected step number"))?
373 } else {
374 1
375 };
376
377 if step == 0 {
378 return Err(custom_error(ctx, "Step cannot be zero"));
379 }
380
381 let mut result = Vec::new();
382 let mut current = start;
383
384 const MAX_RANGE: usize = 10000;
385
386 if step > 0 {
387 while current < end && result.len() < MAX_RANGE {
388 result.push(Value::Number(Number::from(current)));
389 current += step;
390 }
391 } else {
392 while current > end && result.len() < MAX_RANGE {
393 result.push(Value::Number(Number::from(current)));
394 current += step;
395 }
396 }
397
398 Ok(Value::Array(result))
399 }
400}
401
402defn!(IndexAtFn, vec![arg!(array), arg!(number)], None);
407
408impl Function for IndexAtFn {
409 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
410 self.signature.validate(args, ctx)?;
411
412 let arr = args[0]
413 .as_array()
414 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
415
416 let index = args[1]
417 .as_f64()
418 .map(|n| n as i64)
419 .ok_or_else(|| custom_error(ctx, "Expected number for index"))?;
420
421 let len = arr.len() as i64;
422 let actual_index = if index < 0 {
423 (len + index) as usize
424 } else {
425 index as usize
426 };
427
428 if actual_index < arr.len() {
429 Ok(arr[actual_index].clone())
430 } else {
431 Ok(Value::Null)
432 }
433 }
434}
435
436defn!(IncludesFn, vec![arg!(array), arg!(any)], None);
441
442impl Function for IncludesFn {
443 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
444 self.signature.validate(args, ctx)?;
445
446 let arr = args[0]
447 .as_array()
448 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
449
450 let search_key = serde_json::to_string(&args[1]).unwrap_or_default();
451
452 let found = arr.iter().any(|item| {
453 let item_key = serde_json::to_string(item).unwrap_or_default();
454 item_key == search_key
455 });
456
457 Ok(Value::Bool(found))
458 }
459}
460
461defn!(FindIndexFn, vec![arg!(array), arg!(any)], None);
466
467impl Function for FindIndexFn {
468 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
469 self.signature.validate(args, ctx)?;
470
471 let arr = args[0]
472 .as_array()
473 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
474
475 let search_key = serde_json::to_string(&args[1]).unwrap_or_default();
476
477 let index = arr
478 .iter()
479 .position(|item| {
480 let item_key = serde_json::to_string(item).unwrap_or_default();
481 item_key == search_key
482 })
483 .map(|i| i as i64)
484 .unwrap_or(-1);
485
486 Ok(Value::Number(Number::from(index)))
487 }
488}
489
490defn!(FirstFn, vec![arg!(array)], None);
495
496impl Function for FirstFn {
497 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
498 self.signature.validate(args, ctx)?;
499
500 let arr = args[0]
501 .as_array()
502 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
503
504 Ok(arr.first().cloned().unwrap_or(Value::Null))
505 }
506}
507
508defn!(LastFn, vec![arg!(array)], None);
513
514impl Function for LastFn {
515 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
516 self.signature.validate(args, ctx)?;
517
518 let arr = args[0]
519 .as_array()
520 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
521
522 Ok(arr.last().cloned().unwrap_or(Value::Null))
523 }
524}
525
526defn!(GroupByFn, vec![arg!(array), arg!(string)], None);
531
532impl Function for GroupByFn {
533 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
534 self.signature.validate(args, ctx)?;
535
536 let arr = args[0]
537 .as_array()
538 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
539
540 let field_name = args[1]
541 .as_str()
542 .ok_or_else(|| custom_error(ctx, "Expected field name string"))?;
543
544 let mut groups: std::collections::BTreeMap<String, Vec<Value>> =
545 std::collections::BTreeMap::new();
546
547 for item in arr {
548 let key = if let Some(obj) = item.as_object() {
549 if let Some(field_value) = obj.get(field_name) {
550 match field_value {
551 Value::String(s) => s.clone(),
552 Value::Number(n) => n.to_string(),
553 Value::Bool(b) => b.to_string(),
554 Value::Null => "null".to_string(),
555 _ => continue,
556 }
557 } else {
558 "null".to_string()
559 }
560 } else {
561 continue;
562 };
563 groups.entry(key).or_default().push(item.clone());
564 }
565
566 let mut result = serde_json::Map::new();
567 for (k, v) in groups {
568 result.insert(k, Value::Array(v));
569 }
570
571 Ok(Value::Object(result))
572 }
573}
574
575defn!(IndexByFn, vec![arg!(array), arg!(string)], None);
580
581impl Function for IndexByFn {
582 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
583 self.signature.validate(args, ctx)?;
584
585 let arr = args[0]
586 .as_array()
587 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
588
589 let field_name = args[1]
590 .as_str()
591 .ok_or_else(|| custom_error(ctx, "Expected field name string"))?;
592
593 let mut result = serde_json::Map::new();
594
595 for item in arr {
596 let key = if let Some(obj) = item.as_object() {
597 if let Some(field_value) = obj.get(field_name) {
598 match field_value {
599 Value::String(s) => s.clone(),
600 Value::Number(n) => n.to_string(),
601 Value::Bool(b) => b.to_string(),
602 Value::Null => "null".to_string(),
603 _ => continue,
604 }
605 } else {
606 continue;
608 }
609 } else {
610 continue;
611 };
612 result.insert(key, item.clone());
614 }
615
616 Ok(Value::Object(result))
617 }
618}
619
620defn!(NthFn, vec![arg!(array), arg!(number)], None);
625
626impl Function for NthFn {
627 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
628 self.signature.validate(args, ctx)?;
629
630 let arr = args[0]
631 .as_array()
632 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
633
634 let n = args[1]
635 .as_f64()
636 .ok_or_else(|| custom_error(ctx, "Expected number argument"))? as usize;
637
638 if n == 0 {
639 return Ok(Value::Null);
640 }
641
642 let result: Vec<Value> = arr.iter().step_by(n).cloned().collect();
643 Ok(Value::Array(result))
644 }
645}
646
647defn!(InterleaveFn, vec![arg!(array), arg!(array)], None);
652
653impl Function for InterleaveFn {
654 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
655 self.signature.validate(args, ctx)?;
656
657 let arr1 = args[0]
658 .as_array()
659 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
660
661 let arr2 = args[1]
662 .as_array()
663 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
664
665 let mut result = Vec::with_capacity(arr1.len() + arr2.len());
666 let mut iter1 = arr1.iter();
667 let mut iter2 = arr2.iter();
668
669 loop {
670 match (iter1.next(), iter2.next()) {
671 (Some(a), Some(b)) => {
672 result.push(a.clone());
673 result.push(b.clone());
674 }
675 (Some(a), None) => {
676 result.push(a.clone());
677 result.extend(iter1.cloned());
678 break;
679 }
680 (None, Some(b)) => {
681 result.push(b.clone());
682 result.extend(iter2.cloned());
683 break;
684 }
685 (None, None) => break,
686 }
687 }
688
689 Ok(Value::Array(result))
690 }
691}
692
693defn!(RotateFn, vec![arg!(array), arg!(number)], None);
698
699impl Function for RotateFn {
700 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
701 self.signature.validate(args, ctx)?;
702
703 let arr = args[0]
704 .as_array()
705 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
706
707 if arr.is_empty() {
708 return Ok(Value::Array(vec![]));
709 }
710
711 let n = args[1]
712 .as_f64()
713 .ok_or_else(|| custom_error(ctx, "Expected number argument"))? as i64;
714
715 let len = arr.len() as i64;
716 let rotation = ((n % len) + len) % len;
717 let rotation = rotation as usize;
718
719 let mut result = Vec::with_capacity(arr.len());
720 result.extend(arr[rotation..].iter().cloned());
721 result.extend(arr[..rotation].iter().cloned());
722
723 Ok(Value::Array(result))
724 }
725}
726
727defn!(PartitionFn, vec![arg!(array), arg!(number)], None);
732
733impl Function for PartitionFn {
734 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
735 self.signature.validate(args, ctx)?;
736
737 let arr = args[0]
738 .as_array()
739 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
740
741 let n = args[1]
742 .as_f64()
743 .ok_or_else(|| custom_error(ctx, "Expected number argument"))? as usize;
744
745 if n == 0 {
746 return Ok(Value::Null);
747 }
748
749 let len = arr.len();
750 let base_size = len / n;
751 let remainder = len % n;
752
753 let mut result = Vec::with_capacity(n);
754 let mut start = 0;
755
756 for i in 0..n {
757 let size = base_size + if i < remainder { 1 } else { 0 };
758 if size > 0 {
759 result.push(Value::Array(arr[start..start + size].to_vec()));
760 } else {
761 result.push(Value::Array(vec![]));
762 }
763 start += size;
764 }
765
766 Ok(Value::Array(result))
767 }
768}
769
770defn!(DifferenceFn, vec![arg!(array), arg!(array)], None);
775
776impl Function for DifferenceFn {
777 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
778 self.signature.validate(args, ctx)?;
779
780 let arr1 = args[0]
781 .as_array()
782 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
783
784 let arr2 = args[1]
785 .as_array()
786 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
787
788 let set2: HashSet<String> = arr2
789 .iter()
790 .map(|v| serde_json::to_string(v).unwrap_or_default())
791 .collect();
792
793 let result: Vec<Value> = arr1
794 .iter()
795 .filter(|v| {
796 let key = serde_json::to_string(*v).unwrap_or_default();
797 !set2.contains(&key)
798 })
799 .cloned()
800 .collect();
801
802 Ok(Value::Array(result))
803 }
804}
805
806defn!(IntersectionFn, vec![arg!(array), arg!(array)], None);
811
812impl Function for IntersectionFn {
813 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
814 self.signature.validate(args, ctx)?;
815
816 let arr1 = args[0]
817 .as_array()
818 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
819
820 let arr2 = args[1]
821 .as_array()
822 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
823
824 let set2: HashSet<String> = arr2
825 .iter()
826 .map(|v| serde_json::to_string(v).unwrap_or_default())
827 .collect();
828
829 let mut seen: HashSet<String> = HashSet::new();
830 let result: Vec<Value> = arr1
831 .iter()
832 .filter(|v| {
833 let key = serde_json::to_string(*v).unwrap_or_default();
834 set2.contains(&key) && seen.insert(key)
835 })
836 .cloned()
837 .collect();
838
839 Ok(Value::Array(result))
840 }
841}
842
843defn!(UnionFn, vec![arg!(array), arg!(array)], None);
848
849impl Function for UnionFn {
850 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
851 self.signature.validate(args, ctx)?;
852
853 let arr1 = args[0]
854 .as_array()
855 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
856
857 let arr2 = args[1]
858 .as_array()
859 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
860
861 let mut seen: HashSet<String> = HashSet::new();
862 let mut result: Vec<Value> = Vec::new();
863
864 for item in arr1.iter().chain(arr2.iter()) {
865 let key = serde_json::to_string(item).unwrap_or_default();
866 if seen.insert(key) {
867 result.push(item.clone());
868 }
869 }
870
871 Ok(Value::Array(result))
872 }
873}
874
875defn!(FrequenciesFn, vec![arg!(array)], None);
880
881impl Function for FrequenciesFn {
882 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
883 self.signature.validate(args, ctx)?;
884
885 let arr = args[0]
886 .as_array()
887 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
888
889 let mut counts: std::collections::HashMap<String, i64> = std::collections::HashMap::new();
890
891 for item in arr {
892 let key = match item {
893 Value::String(s) => s.clone(),
894 Value::Number(n) => n.to_string(),
895 Value::Bool(b) => b.to_string(),
896 Value::Null => "null".to_string(),
897 _ => serde_json::to_string(item).unwrap_or_else(|_| "null".to_string()),
898 };
899 *counts.entry(key).or_insert(0) += 1;
900 }
901
902 let mut result = serde_json::Map::new();
903 let sorted: std::collections::BTreeMap<String, i64> = counts.into_iter().collect();
905 for (k, v) in sorted {
906 result.insert(k, Value::Number(Number::from(v)));
907 }
908
909 Ok(Value::Object(result))
910 }
911}
912
913defn!(ModeFn, vec![arg!(array)], None);
918
919impl Function for ModeFn {
920 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
921 self.signature.validate(args, ctx)?;
922
923 let arr = args[0]
924 .as_array()
925 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
926
927 if arr.is_empty() {
928 return Ok(Value::Null);
929 }
930
931 let mut counts: std::collections::HashMap<String, (i64, Value)> =
932 std::collections::HashMap::new();
933
934 for item in arr {
935 let key = serde_json::to_string(item).unwrap_or_default();
936 counts
937 .entry(key)
938 .and_modify(|(count, _)| *count += 1)
939 .or_insert((1, item.clone()));
940 }
941
942 let (_, (_, mode_value)) = counts
943 .into_iter()
944 .max_by_key(|(_, (count, _))| *count)
945 .unwrap();
946
947 Ok(mode_value)
948 }
949}
950
951defn!(CartesianFn, vec![arg!(array)], Some(arg!(array)));
957
958impl Function for CartesianFn {
959 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
960 self.signature.validate(args, ctx)?;
961
962 let first = args[0]
963 .as_array()
964 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
965
966 if args.len() == 2 {
971 let arr2 = args[1]
973 .as_array()
974 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
975
976 let mut result = Vec::with_capacity(first.len() * arr2.len());
977 for a in first {
978 for b in arr2 {
979 result.push(Value::Array(vec![a.clone(), b.clone()]));
980 }
981 }
982 Ok(Value::Array(result))
983 } else {
984 let arrays: Vec<&Vec<Value>> =
987 first.iter().filter_map(|item| item.as_array()).collect();
988
989 if arrays.len() != first.len() || arrays.is_empty() {
990 return Ok(Value::Array(vec![]));
992 }
993
994 let result = cartesian_product_n(&arrays);
996 Ok(Value::Array(result))
997 }
998 }
999}
1000
1001fn cartesian_product_n(arrays: &[&Vec<Value>]) -> Vec<Value> {
1003 if arrays.is_empty() {
1004 return vec![];
1005 }
1006
1007 if arrays.len() == 1 {
1008 return arrays[0]
1010 .iter()
1011 .map(|item| Value::Array(vec![item.clone()]))
1012 .collect();
1013 }
1014
1015 let total_size: usize = arrays.iter().map(|a| a.len()).product();
1017 if total_size == 0 {
1018 return vec![];
1019 }
1020
1021 let mut result = Vec::with_capacity(total_size);
1022
1023 let mut indices = vec![0usize; arrays.len()];
1025
1026 loop {
1027 let combo: Vec<Value> = indices
1029 .iter()
1030 .enumerate()
1031 .map(|(arr_idx, &elem_idx)| arrays[arr_idx][elem_idx].clone())
1032 .collect();
1033 result.push(Value::Array(combo));
1034
1035 let mut carry = true;
1037 for i in (0..arrays.len()).rev() {
1038 if carry {
1039 indices[i] += 1;
1040 if indices[i] >= arrays[i].len() {
1041 indices[i] = 0;
1042 } else {
1043 carry = false;
1044 }
1045 }
1046 }
1047
1048 if carry {
1050 break;
1051 }
1052 }
1053
1054 result
1055}
1056
1057defn!(InitialFn, vec![arg!(array)], None);
1062
1063impl Function for InitialFn {
1064 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1065 self.signature.validate(args, ctx)?;
1066
1067 let arr = args[0]
1068 .as_array()
1069 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1070
1071 if arr.is_empty() {
1072 return Ok(Value::Array(vec![]));
1073 }
1074
1075 let result: Vec<Value> = arr[..arr.len() - 1].to_vec();
1076 Ok(Value::Array(result))
1077 }
1078}
1079
1080defn!(InterposeFn, vec![arg!(array), arg!(any)], None);
1085
1086impl Function for InterposeFn {
1087 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1088 self.signature.validate(args, ctx)?;
1089
1090 let arr = args[0]
1091 .as_array()
1092 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1093
1094 let separator = args[1].clone();
1095
1096 if arr.is_empty() {
1097 return Ok(Value::Array(vec![]));
1098 }
1099
1100 if arr.len() == 1 {
1101 return Ok(Value::Array(arr.clone()));
1102 }
1103
1104 let mut result = Vec::with_capacity(arr.len() * 2 - 1);
1105 for (i, item) in arr.iter().enumerate() {
1106 if i > 0 {
1107 result.push(separator.clone());
1108 }
1109 result.push(item.clone());
1110 }
1111
1112 Ok(Value::Array(result))
1113 }
1114}
1115
1116defn!(ZipmapFn, vec![arg!(array), arg!(array)], None);
1121
1122impl Function for ZipmapFn {
1123 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1124 self.signature.validate(args, ctx)?;
1125
1126 let keys = args[0]
1127 .as_array()
1128 .ok_or_else(|| custom_error(ctx, "Expected array argument for keys"))?;
1129
1130 let values = args[1]
1131 .as_array()
1132 .ok_or_else(|| custom_error(ctx, "Expected array argument for values"))?;
1133
1134 let len = keys.len().min(values.len());
1135 let mut result = serde_json::Map::new();
1136
1137 for i in 0..len {
1138 let key = keys[i]
1139 .as_str()
1140 .ok_or_else(|| custom_error(ctx, "Keys must be strings"))?;
1141 result.insert(key.to_string(), values[i].clone());
1142 }
1143
1144 Ok(Value::Object(result))
1145 }
1146}
1147
1148defn!(PartitionByFn, vec![arg!(array), arg!(string)], None);
1153
1154impl Function for PartitionByFn {
1155 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1156 self.signature.validate(args, ctx)?;
1157
1158 let arr = args[0]
1159 .as_array()
1160 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1161
1162 let field_name = args[1]
1163 .as_str()
1164 .ok_or_else(|| custom_error(ctx, "Expected field name string"))?;
1165
1166 if arr.is_empty() {
1167 return Ok(Value::Array(vec![]));
1168 }
1169
1170 let mut result: Vec<Value> = Vec::new();
1171 let mut current_partition: Vec<Value> = Vec::new();
1172 let mut last_key: Option<String> = None;
1173
1174 for item in arr {
1175 let key = if let Some(obj) = item.as_object() {
1177 if let Some(field_value) = obj.get(field_name) {
1178 serde_json::to_string(field_value).unwrap_or_default()
1179 } else {
1180 "null".to_string()
1181 }
1182 } else {
1183 serde_json::to_string(item).unwrap_or_default()
1185 };
1186
1187 match &last_key {
1188 Some(prev_key) if *prev_key == key => {
1189 current_partition.push(item.clone());
1190 }
1191 _ => {
1192 if !current_partition.is_empty() {
1193 result.push(Value::Array(current_partition));
1194 }
1195 current_partition = vec![item.clone()];
1196 last_key = Some(key);
1197 }
1198 }
1199 }
1200
1201 if !current_partition.is_empty() {
1203 result.push(Value::Array(current_partition));
1204 }
1205
1206 Ok(Value::Array(result))
1207 }
1208}
1209
1210defn!(DedupeFn, vec![arg!(array)], None);
1215
1216impl Function for DedupeFn {
1217 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1218 self.signature.validate(args, ctx)?;
1219
1220 let arr = args[0]
1221 .as_array()
1222 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1223
1224 if arr.is_empty() {
1225 return Ok(Value::Array(vec![]));
1226 }
1227
1228 let mut result: Vec<Value> = Vec::with_capacity(arr.len());
1229 let mut last_key: Option<String> = None;
1230
1231 for item in arr {
1232 let key = serde_json::to_string(item).unwrap_or_default();
1233 match &last_key {
1234 Some(prev_key) if *prev_key == key => {
1235 }
1237 _ => {
1238 result.push(item.clone());
1239 last_key = Some(key);
1240 }
1241 }
1242 }
1243
1244 Ok(Value::Array(result))
1245 }
1246}
1247
1248defn!(TailFn, vec![arg!(array)], None);
1253
1254impl Function for TailFn {
1255 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1256 self.signature.validate(args, ctx)?;
1257
1258 let arr = args[0]
1259 .as_array()
1260 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1261
1262 if arr.is_empty() {
1263 return Ok(Value::Array(vec![]));
1264 }
1265
1266 let result: Vec<Value> = arr[1..].to_vec();
1267 Ok(Value::Array(result))
1268 }
1269}
1270
1271defn!(WithoutFn, vec![arg!(array), arg!(array)], None);
1276
1277impl Function for WithoutFn {
1278 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1279 self.signature.validate(args, ctx)?;
1280
1281 let arr = args[0]
1282 .as_array()
1283 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1284
1285 let exclude = args[1]
1286 .as_array()
1287 .ok_or_else(|| custom_error(ctx, "Expected array argument for values to exclude"))?;
1288
1289 let exclude_set: HashSet<String> = exclude
1291 .iter()
1292 .map(|v| serde_json::to_string(v).unwrap_or_default())
1293 .collect();
1294
1295 let result: Vec<Value> = arr
1296 .iter()
1297 .filter(|item| {
1298 let key = serde_json::to_string(*item).unwrap_or_default();
1299 !exclude_set.contains(&key)
1300 })
1301 .cloned()
1302 .collect();
1303
1304 Ok(Value::Array(result))
1305 }
1306}
1307
1308defn!(XorFn, vec![arg!(array), arg!(array)], None);
1313
1314impl Function for XorFn {
1315 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1316 self.signature.validate(args, ctx)?;
1317
1318 let arr1 = args[0]
1319 .as_array()
1320 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1321
1322 let arr2 = args[1]
1323 .as_array()
1324 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1325
1326 let set1: HashSet<String> = arr1
1328 .iter()
1329 .map(|v| serde_json::to_string(v).unwrap_or_default())
1330 .collect();
1331
1332 let set2: HashSet<String> = arr2
1333 .iter()
1334 .map(|v| serde_json::to_string(v).unwrap_or_default())
1335 .collect();
1336
1337 let mut result = Vec::new();
1338
1339 for item in arr1 {
1341 let key = serde_json::to_string(item).unwrap_or_default();
1342 if !set2.contains(&key) {
1343 result.push(item.clone());
1344 }
1345 }
1346
1347 for item in arr2 {
1349 let key = serde_json::to_string(item).unwrap_or_default();
1350 if !set1.contains(&key) {
1351 result.push(item.clone());
1352 }
1353 }
1354
1355 Ok(Value::Array(result))
1356 }
1357}
1358
1359defn!(
1364 WindowFn,
1365 vec![arg!(array), arg!(number)],
1366 Some(arg!(number))
1367);
1368
1369impl Function for WindowFn {
1370 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1371 self.signature.validate(args, ctx)?;
1372
1373 let arr = args[0]
1374 .as_array()
1375 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1376
1377 let size = args[1]
1378 .as_f64()
1379 .ok_or_else(|| custom_error(ctx, "Expected number for window size"))?
1380 as usize;
1381
1382 if size == 0 {
1383 return Ok(Value::Array(vec![]));
1384 }
1385
1386 let step = if args.len() > 2 {
1388 args[2]
1389 .as_f64()
1390 .ok_or_else(|| custom_error(ctx, "Expected number for step"))? as usize
1391 } else {
1392 1
1393 };
1394
1395 if step == 0 {
1396 return Err(custom_error(ctx, "Step cannot be zero"));
1397 }
1398
1399 let len = arr.len();
1400 if len < size {
1401 return Ok(Value::Array(vec![]));
1402 }
1403
1404 let mut result = Vec::new();
1405 let mut i = 0;
1406
1407 while i + size <= len {
1408 let window: Vec<Value> = arr[i..i + size].to_vec();
1409 result.push(Value::Array(window));
1410 i += step;
1411 }
1412
1413 Ok(Value::Array(result))
1414 }
1415}
1416
1417defn!(CombinationsFn, vec![arg!(array), arg!(number)], None);
1422
1423fn generate_combinations(arr: &[Value], k: usize) -> Vec<Vec<Value>> {
1424 if k == 0 {
1425 return vec![vec![]];
1426 }
1427 if arr.len() < k {
1428 return vec![];
1429 }
1430
1431 let mut result = Vec::new();
1432
1433 let first = arr[0].clone();
1435 let rest = &arr[1..];
1436 for mut combo in generate_combinations(rest, k - 1) {
1437 let mut new_combo = vec![first.clone()];
1438 new_combo.append(&mut combo);
1439 result.push(new_combo);
1440 }
1441
1442 result.extend(generate_combinations(rest, k));
1444
1445 result
1446}
1447
1448impl Function for CombinationsFn {
1449 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1450 self.signature.validate(args, ctx)?;
1451
1452 let arr = args[0]
1453 .as_array()
1454 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1455
1456 let k = args[1]
1457 .as_f64()
1458 .ok_or_else(|| custom_error(ctx, "Expected number for k"))? as usize;
1459
1460 const MAX_COMBINATIONS: usize = 10000;
1462
1463 let n = arr.len();
1465 if n > 20 && k > 3 && k < n - 3 {
1466 return Err(custom_error(ctx, "Combination size too large"));
1467 }
1468
1469 let combinations = generate_combinations(arr, k);
1470
1471 if combinations.len() > MAX_COMBINATIONS {
1472 return Err(custom_error(ctx, "Too many combinations generated"));
1473 }
1474
1475 let result: Vec<Value> = combinations.into_iter().map(Value::Array).collect();
1476
1477 Ok(Value::Array(result))
1478 }
1479}
1480
1481defn!(FillFn, vec![arg!(array), arg!(any)], Some(arg!(number)));
1486
1487impl Function for FillFn {
1488 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1489 self.signature.validate(args, ctx)?;
1490
1491 let arr = args[0]
1492 .as_array()
1493 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1494
1495 let fill_value = args[1].clone();
1496
1497 let len = arr.len();
1498 if len == 0 {
1499 return Ok(Value::Array(vec![]));
1500 }
1501
1502 let start = if args.len() > 2 {
1504 let s = args[2]
1505 .as_f64()
1506 .ok_or_else(|| custom_error(ctx, "Expected number for start index"))?
1507 as i64;
1508 if s < 0 {
1510 (len as i64 + s).max(0) as usize
1511 } else {
1512 (s as usize).min(len)
1513 }
1514 } else {
1515 0
1516 };
1517
1518 let end = if args.len() > 3 {
1519 let e = args[3]
1520 .as_f64()
1521 .ok_or_else(|| custom_error(ctx, "Expected number for end index"))?
1522 as i64;
1523 if e < 0 {
1525 (len as i64 + e).max(0) as usize
1526 } else {
1527 (e as usize).min(len)
1528 }
1529 } else {
1530 len
1531 };
1532
1533 let mut result: Vec<Value> = arr.clone();
1534
1535 for item in result.iter_mut().take(end.min(len)).skip(start) {
1536 *item = fill_value.clone();
1537 }
1538
1539 Ok(Value::Array(result))
1540 }
1541}
1542
1543defn!(PullAtFn, vec![arg!(array), arg!(array)], None);
1548
1549impl Function for PullAtFn {
1550 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1551 self.signature.validate(args, ctx)?;
1552
1553 let arr = args[0]
1554 .as_array()
1555 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1556
1557 let indices = args[1]
1558 .as_array()
1559 .ok_or_else(|| custom_error(ctx, "Expected array of indices"))?;
1560
1561 let len = arr.len();
1562 let mut result = Vec::new();
1563
1564 for idx_var in indices {
1565 let idx = idx_var
1566 .as_f64()
1567 .ok_or_else(|| custom_error(ctx, "Expected number in indices array"))?
1568 as i64;
1569
1570 let actual_idx = if idx < 0 {
1572 (len as i64 + idx).max(0) as usize
1573 } else {
1574 idx as usize
1575 };
1576
1577 if actual_idx < len {
1578 result.push(arr[actual_idx].clone());
1579 }
1580 }
1581
1582 Ok(Value::Array(result))
1583 }
1584}
1585
1586defn!(TransposeFn, vec![arg!(array)], None);
1591
1592impl Function for TransposeFn {
1593 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1594 self.signature.validate(args, ctx)?;
1595
1596 let arr = args[0]
1597 .as_array()
1598 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1599
1600 if arr.is_empty() {
1601 return Ok(Value::Array(vec![]));
1602 }
1603
1604 let mut inner_arrays: Vec<&Vec<Value>> = Vec::new();
1606 let mut min_len = usize::MAX;
1607
1608 for item in arr {
1609 if let Some(inner) = item.as_array() {
1610 min_len = min_len.min(inner.len());
1611 inner_arrays.push(inner);
1612 } else {
1613 return Ok(Value::Array(vec![]));
1615 }
1616 }
1617
1618 if inner_arrays.is_empty() || min_len == 0 {
1619 return Ok(Value::Array(vec![]));
1620 }
1621
1622 let mut result = Vec::with_capacity(min_len);
1624 for i in 0..min_len {
1625 let mut row = Vec::with_capacity(inner_arrays.len());
1626 for inner in &inner_arrays {
1627 row.push(inner[i].clone());
1628 }
1629 result.push(Value::Array(row));
1630 }
1631
1632 Ok(Value::Array(result))
1633 }
1634}
1635
1636defn!(PairwiseFn, vec![arg!(array)], None);
1641
1642impl Function for PairwiseFn {
1643 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1644 self.signature.validate(args, ctx)?;
1645
1646 let arr = args[0]
1647 .as_array()
1648 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1649
1650 if arr.len() < 2 {
1651 return Ok(Value::Array(vec![]));
1652 }
1653
1654 let mut result = Vec::with_capacity(arr.len() - 1);
1655 for i in 0..arr.len() - 1 {
1656 let pair = vec![arr[i].clone(), arr[i + 1].clone()];
1657 result.push(Value::Array(pair));
1658 }
1659
1660 Ok(Value::Array(result))
1661 }
1662}
1663
1664defn!(IndicesArrayFn, vec![arg!(array), arg!(any)], None);
1669
1670impl Function for IndicesArrayFn {
1671 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1672 self.signature.validate(args, ctx)?;
1673
1674 let arr = args[0]
1675 .as_array()
1676 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1677
1678 let search_key = serde_json::to_string(&args[1]).unwrap_or_default();
1679
1680 let mut indices: Vec<Value> = Vec::new();
1681 for (i, item) in arr.iter().enumerate() {
1682 let item_key = serde_json::to_string(item).unwrap_or_default();
1683 if item_key == search_key {
1684 indices.push(Value::Number(Number::from(i as i64)));
1685 }
1686 }
1687
1688 Ok(Value::Array(indices))
1689 }
1690}
1691
1692defn!(InsideArrayFn, vec![arg!(array), arg!(array)], None);
1697
1698impl Function for InsideArrayFn {
1699 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1700 self.signature.validate(args, ctx)?;
1701
1702 let needle = args[0]
1703 .as_array()
1704 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1705
1706 let haystack = args[1]
1707 .as_array()
1708 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1709
1710 let haystack_set: HashSet<String> = haystack
1712 .iter()
1713 .map(|item| serde_json::to_string(item).unwrap_or_default())
1714 .collect();
1715
1716 let result = needle.iter().all(|item| {
1718 let item_key = serde_json::to_string(item).unwrap_or_default();
1719 haystack_set.contains(&item_key)
1720 });
1721
1722 Ok(Value::Bool(result))
1723 }
1724}
1725
1726defn!(BsearchFn, vec![arg!(array), arg!(any)], None);
1731
1732impl Function for BsearchFn {
1733 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1734 self.signature.validate(args, ctx)?;
1735
1736 let arr = args[0]
1737 .as_array()
1738 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1739
1740 let target = &args[1];
1741
1742 if arr.is_empty() {
1743 return Ok(Value::Number(Number::from(-1)));
1744 }
1745
1746 fn compare_values(a: &Value, b: &Value) -> std::cmp::Ordering {
1749 match (a, b) {
1750 (Value::Number(n1), Value::Number(n2)) => {
1752 let f1 = n1.as_f64().unwrap_or(0.0);
1753 let f2 = n2.as_f64().unwrap_or(0.0);
1754 f1.partial_cmp(&f2).unwrap_or(std::cmp::Ordering::Equal)
1755 }
1756 (Value::String(s1), Value::String(s2)) => s1.cmp(s2),
1758 (Value::Bool(b1), Value::Bool(b2)) => b1.cmp(b2),
1760 _ => {
1762 let s1 = serde_json::to_string(a).unwrap_or_default();
1763 let s2 = serde_json::to_string(b).unwrap_or_default();
1764 s1.cmp(&s2)
1765 }
1766 }
1767 }
1768
1769 let mut left = 0i64;
1770 let mut right = arr.len() as i64 - 1;
1771
1772 while left <= right {
1773 let mid = left + (right - left) / 2;
1774
1775 match compare_values(&arr[mid as usize], target) {
1776 std::cmp::Ordering::Equal => {
1777 return Ok(Value::Number(Number::from(mid)));
1778 }
1779 std::cmp::Ordering::Less => {
1780 left = mid + 1;
1781 }
1782 std::cmp::Ordering::Greater => {
1783 right = mid - 1;
1784 }
1785 }
1786 }
1787
1788 let result = -(left) - 1;
1791 Ok(Value::Number(Number::from(result)))
1792 }
1793}
1794
1795defn!(RepeatArrayFn, vec![arg!(any), arg!(number)], None);
1800
1801impl Function for RepeatArrayFn {
1802 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1803 self.signature.validate(args, ctx)?;
1804
1805 let value = &args[0];
1806 let n = args[1]
1807 .as_f64()
1808 .ok_or_else(|| custom_error(ctx, "Expected number for count argument"))?
1809 as i64;
1810
1811 if n < 0 {
1812 return Err(custom_error(ctx, "Count must be non-negative"));
1813 }
1814
1815 let result: Vec<Value> = (0..n).map(|_| value.clone()).collect();
1816 Ok(Value::Array(result))
1817 }
1818}
1819
1820defn!(CycleFn, vec![arg!(array), arg!(number)], None);
1825
1826impl Function for CycleFn {
1827 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1828 self.signature.validate(args, ctx)?;
1829
1830 let arr = args[0]
1831 .as_array()
1832 .ok_or_else(|| custom_error(ctx, "Expected array argument"))?;
1833
1834 let n = args[1]
1835 .as_f64()
1836 .ok_or_else(|| custom_error(ctx, "Expected number for count argument"))?
1837 as i64;
1838
1839 if n < 0 {
1840 return Err(custom_error(ctx, "Count must be non-negative"));
1841 }
1842
1843 if arr.is_empty() || n == 0 {
1844 return Ok(Value::Array(vec![]));
1845 }
1846
1847 let mut result: Vec<Value> = Vec::with_capacity(arr.len() * n as usize);
1848 for _ in 0..n {
1849 result.extend(arr.iter().cloned());
1850 }
1851 Ok(Value::Array(result))
1852 }
1853}
1854
1855defn!(LagFn, vec![arg!(array), arg!(number)], None);
1860
1861impl Function for LagFn {
1862 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1863 self.signature.validate(args, ctx)?;
1864 let arr = args[0].as_array().unwrap();
1865 let n = args[1].as_f64().unwrap() as usize;
1866 let len = arr.len();
1867 let mut result = Vec::with_capacity(len);
1868 for _ in 0..n.min(len) {
1869 result.push(Value::Null);
1870 }
1871 if n < len {
1872 result.extend_from_slice(&arr[..len - n]);
1873 }
1874 Ok(Value::Array(result))
1875 }
1876}
1877
1878defn!(LeadFn, vec![arg!(array), arg!(number)], None);
1883
1884impl Function for LeadFn {
1885 fn evaluate(&self, args: &[Value], ctx: &mut Context<'_>) -> SearchResult {
1886 self.signature.validate(args, ctx)?;
1887 let arr = args[0].as_array().unwrap();
1888 let n = args[1].as_f64().unwrap() as usize;
1889 let len = arr.len();
1890 let mut result = Vec::with_capacity(len);
1891 if n < len {
1892 result.extend_from_slice(&arr[n..]);
1893 }
1894 let remaining = len.saturating_sub(result.len());
1895 for _ in 0..remaining {
1896 result.push(Value::Null);
1897 }
1898 Ok(Value::Array(result))
1899 }
1900}
1901
1902#[cfg(test)]
1903mod tests {
1904 use crate::Runtime;
1905 use serde_json::json;
1906
1907 fn setup_runtime() -> Runtime {
1908 Runtime::builder()
1909 .with_standard()
1910 .with_all_extensions()
1911 .build()
1912 }
1913
1914 #[test]
1915 fn test_unique() {
1916 let runtime = setup_runtime();
1917 let expr = runtime.compile("unique(@)").unwrap();
1918 let data = json!([1, 2, 1]);
1919 let result = expr.search(&data).unwrap();
1920 let arr = result.as_array().unwrap();
1921 assert_eq!(arr.len(), 2);
1922 }
1923
1924 #[test]
1925 fn test_first() {
1926 let runtime = setup_runtime();
1927 let expr = runtime.compile("first(@)").unwrap();
1928 let data = json!([1, 2]);
1929 let result = expr.search(&data).unwrap();
1930 assert_eq!(result.as_f64().unwrap() as i64, 1);
1931 }
1932
1933 #[test]
1934 fn test_last() {
1935 let runtime = setup_runtime();
1936 let expr = runtime.compile("last(@)").unwrap();
1937 let data = json!([1, 2]);
1938 let result = expr.search(&data).unwrap();
1939 assert_eq!(result.as_f64().unwrap() as i64, 2);
1940 }
1941
1942 #[test]
1943 fn test_range() {
1944 let runtime = setup_runtime();
1945 let expr = runtime.compile("range(`0`, `5`)").unwrap();
1946 let data = json!(null);
1947 let result = expr.search(&data).unwrap();
1948 let arr = result.as_array().unwrap();
1949 assert_eq!(arr.len(), 5);
1950 }
1951
1952 #[test]
1953 fn test_butlast() {
1954 let runtime = setup_runtime();
1956 let expr = runtime.compile("butlast(@)").unwrap();
1957 let data = json!([1, 2, 3]);
1958 let result = expr.search(&data).unwrap();
1959 let arr = result.as_array().unwrap();
1960 assert_eq!(arr.len(), 2);
1961 assert_eq!(arr[0].as_f64().unwrap() as i64, 1);
1962 assert_eq!(arr[1].as_f64().unwrap() as i64, 2);
1963 }
1964
1965 #[test]
1966 fn test_interpose() {
1967 let runtime = setup_runtime();
1968 let expr = runtime.compile("interpose(@, `0`)").unwrap();
1969 let data = json!([1, 2, 3]);
1970 let result = expr.search(&data).unwrap();
1971 let arr = result.as_array().unwrap();
1972 assert_eq!(arr.len(), 5);
1973 assert_eq!(arr[0].as_f64().unwrap() as i64, 1);
1974 assert_eq!(arr[1].as_f64().unwrap() as i64, 0);
1975 assert_eq!(arr[2].as_f64().unwrap() as i64, 2);
1976 assert_eq!(arr[3].as_f64().unwrap() as i64, 0);
1977 assert_eq!(arr[4].as_f64().unwrap() as i64, 3);
1978 }
1979
1980 #[test]
1981 fn test_interpose_empty() {
1982 let runtime = setup_runtime();
1983 let expr = runtime.compile("interpose(@, `0`)").unwrap();
1984 let data = json!([]);
1985 let result = expr.search(&data).unwrap();
1986 let arr = result.as_array().unwrap();
1987 assert_eq!(arr.len(), 0);
1988 }
1989
1990 #[test]
1991 fn test_interpose_single() {
1992 let runtime = setup_runtime();
1993 let expr = runtime.compile("interpose(@, `0`)").unwrap();
1994 let data = json!([1]);
1995 let result = expr.search(&data).unwrap();
1996 let arr = result.as_array().unwrap();
1997 assert_eq!(arr.len(), 1);
1998 assert_eq!(arr[0].as_f64().unwrap() as i64, 1);
1999 }
2000
2001 #[test]
2002 fn test_interpose_string_separator() {
2003 let runtime = setup_runtime();
2004 let expr = runtime.compile("interpose(@, `\"-\"`)").unwrap();
2005 let data = json!(["a", "b", "c"]);
2006 let result = expr.search(&data).unwrap();
2007 let arr = result.as_array().unwrap();
2008 assert_eq!(arr.len(), 5);
2009 assert_eq!(arr[0].as_str().unwrap(), "a");
2010 assert_eq!(arr[1].as_str().unwrap(), "-");
2011 assert_eq!(arr[2].as_str().unwrap(), "b");
2012 assert_eq!(arr[3].as_str().unwrap(), "-");
2013 assert_eq!(arr[4].as_str().unwrap(), "c");
2014 }
2015
2016 #[test]
2017 fn test_zipmap() {
2018 let runtime = setup_runtime();
2019 let expr = runtime
2020 .compile("zipmap(`[\"a\", \"b\", \"c\"]`, `[1, 2, 3]`)")
2021 .unwrap();
2022 let data = json!(null);
2023 let result = expr.search(&data).unwrap();
2024 let obj = result.as_object().unwrap();
2025 assert_eq!(obj.len(), 3);
2026 assert_eq!(obj.get("a").unwrap().as_f64().unwrap() as i64, 1);
2027 assert_eq!(obj.get("b").unwrap().as_f64().unwrap() as i64, 2);
2028 assert_eq!(obj.get("c").unwrap().as_f64().unwrap() as i64, 3);
2029 }
2030
2031 #[test]
2032 fn test_zipmap_unequal_lengths() {
2033 let runtime = setup_runtime();
2034 let expr = runtime
2036 .compile("zipmap(`[\"x\", \"y\"]`, `[10, 20, 30]`)")
2037 .unwrap();
2038 let data = json!(null);
2039 let result = expr.search(&data).unwrap();
2040 let obj = result.as_object().unwrap();
2041 assert_eq!(obj.len(), 2);
2042 assert_eq!(obj.get("x").unwrap().as_f64().unwrap() as i64, 10);
2043 assert_eq!(obj.get("y").unwrap().as_f64().unwrap() as i64, 20);
2044 }
2045
2046 #[test]
2047 fn test_zipmap_empty() {
2048 let runtime = setup_runtime();
2049 let expr = runtime.compile("zipmap(`[]`, `[]`)").unwrap();
2050 let data = json!(null);
2051 let result = expr.search(&data).unwrap();
2052 let obj = result.as_object().unwrap();
2053 assert_eq!(obj.len(), 0);
2054 }
2055
2056 #[test]
2057 fn test_partition_by() {
2058 let runtime = setup_runtime();
2059 let expr = runtime.compile(r#"partition_by(@, `"type"`)"#).unwrap();
2061 let data: serde_json::Value = serde_json::from_str(
2062 r#"[{"type": "a", "v": 1}, {"type": "a", "v": 2}, {"type": "b", "v": 3}, {"type": "a", "v": 4}]"#,
2063 )
2064 .unwrap();
2065 let result = expr.search(&data).unwrap();
2066 let arr = result.as_array().unwrap();
2067 assert_eq!(arr.len(), 3);
2068
2069 let partition1 = arr[0].as_array().unwrap();
2070 assert_eq!(partition1.len(), 2); let partition2 = arr[1].as_array().unwrap();
2073 assert_eq!(partition2.len(), 1); let partition3 = arr[2].as_array().unwrap();
2076 assert_eq!(partition3.len(), 1); }
2078
2079 #[test]
2080 fn test_partition_by_primitives() {
2081 let runtime = setup_runtime();
2082 let expr = runtime.compile(r#"partition_by(@, `"_"`)"#).unwrap();
2084 let data = json!([1, 1, 2, 2, 1, 1]);
2085 let result = expr.search(&data).unwrap();
2086 let arr = result.as_array().unwrap();
2087 assert_eq!(arr.len(), 3);
2088
2089 let partition1 = arr[0].as_array().unwrap();
2090 assert_eq!(partition1.len(), 2);
2091 assert_eq!(partition1[0].as_f64().unwrap() as i64, 1);
2092
2093 let partition2 = arr[1].as_array().unwrap();
2094 assert_eq!(partition2.len(), 2);
2095 assert_eq!(partition2[0].as_f64().unwrap() as i64, 2);
2096
2097 let partition3 = arr[2].as_array().unwrap();
2098 assert_eq!(partition3.len(), 2);
2099 assert_eq!(partition3[0].as_f64().unwrap() as i64, 1);
2100 }
2101
2102 #[test]
2103 fn test_partition_by_empty() {
2104 let runtime = setup_runtime();
2105 let expr = runtime.compile(r#"partition_by(@, `"type"`)"#).unwrap();
2106 let data = json!([]);
2107 let result = expr.search(&data).unwrap();
2108 let arr = result.as_array().unwrap();
2109 assert_eq!(arr.len(), 0);
2110 }
2111
2112 #[test]
2113 fn test_partition_by_single() {
2114 let runtime = setup_runtime();
2115 let expr = runtime.compile(r#"partition_by(@, `"type"`)"#).unwrap();
2116 let data: serde_json::Value = serde_json::from_str(r#"[{"type": "a"}]"#).unwrap();
2117 let result = expr.search(&data).unwrap();
2118 let arr = result.as_array().unwrap();
2119 assert_eq!(arr.len(), 1);
2120 let partition1 = arr[0].as_array().unwrap();
2121 assert_eq!(partition1.len(), 1);
2122 }
2123
2124 #[test]
2125 fn test_dedupe() {
2126 let runtime = setup_runtime();
2127 let expr = runtime.compile("dedupe(@)").unwrap();
2128 let data = json!([1, 1, 2, 2, 1, 1]);
2129 let result = expr.search(&data).unwrap();
2130 let arr = result.as_array().unwrap();
2131 assert_eq!(arr.len(), 3);
2132 assert_eq!(arr[0].as_f64().unwrap() as i64, 1);
2133 assert_eq!(arr[1].as_f64().unwrap() as i64, 2);
2134 assert_eq!(arr[2].as_f64().unwrap() as i64, 1);
2135 }
2136
2137 #[test]
2138 fn test_dedupe_empty() {
2139 let runtime = setup_runtime();
2140 let expr = runtime.compile("dedupe(@)").unwrap();
2141 let data = json!([]);
2142 let result = expr.search(&data).unwrap();
2143 let arr = result.as_array().unwrap();
2144 assert_eq!(arr.len(), 0);
2145 }
2146
2147 #[test]
2148 fn test_dedupe_no_consecutive() {
2149 let runtime = setup_runtime();
2150 let expr = runtime.compile("dedupe(@)").unwrap();
2151 let data = json!([1, 2, 3]);
2152 let result = expr.search(&data).unwrap();
2153 let arr = result.as_array().unwrap();
2154 assert_eq!(arr.len(), 3);
2155 }
2156
2157 #[test]
2158 fn test_dedupe_strings() {
2159 let runtime = setup_runtime();
2160 let expr = runtime.compile("dedupe(@)").unwrap();
2161 let data = json!(["a", "a", "b", "a"]);
2162 let result = expr.search(&data).unwrap();
2163 let arr = result.as_array().unwrap();
2164 assert_eq!(arr.len(), 3);
2165 assert_eq!(arr[0].as_str().unwrap(), "a");
2166 assert_eq!(arr[1].as_str().unwrap(), "b");
2167 assert_eq!(arr[2].as_str().unwrap(), "a");
2168 }
2169
2170 #[test]
2171 fn test_dedupe_objects() {
2172 let runtime = setup_runtime();
2173 let expr = runtime.compile("dedupe(@)").unwrap();
2174 let data: serde_json::Value =
2175 serde_json::from_str(r#"[{"x": 1}, {"x": 1}, {"x": 2}, {"x": 1}]"#).unwrap();
2176 let result = expr.search(&data).unwrap();
2177 let arr = result.as_array().unwrap();
2178 assert_eq!(arr.len(), 3);
2179 }
2180
2181 #[test]
2182 fn test_dedupe_all_same() {
2183 let runtime = setup_runtime();
2184 let expr = runtime.compile("dedupe(@)").unwrap();
2185 let data = json!([1, 1, 1]);
2186 let result = expr.search(&data).unwrap();
2187 let arr = result.as_array().unwrap();
2188 assert_eq!(arr.len(), 1);
2189 assert_eq!(arr[0].as_f64().unwrap() as i64, 1);
2190 }
2191
2192 #[test]
2193 fn test_zipmap_duplicate_keys() {
2194 let runtime = setup_runtime();
2196 let expr = runtime
2197 .compile("zipmap(`[\"a\", \"b\", \"a\"]`, `[1, 2, 3]`)")
2198 .unwrap();
2199 let data = json!(null);
2200 let result = expr.search(&data).unwrap();
2201 let obj = result.as_object().unwrap();
2202 assert_eq!(obj.len(), 2);
2203 assert_eq!(obj.get("a").unwrap().as_f64().unwrap() as i64, 3); assert_eq!(obj.get("b").unwrap().as_f64().unwrap() as i64, 2);
2205 }
2206
2207 #[test]
2208 fn test_zipmap_values_longer() {
2209 let runtime = setup_runtime();
2210 let expr = runtime.compile("zipmap(`[\"a\"]`, `[1, 2, 3]`)").unwrap();
2211 let data = json!(null);
2212 let result = expr.search(&data).unwrap();
2213 let obj = result.as_object().unwrap();
2214 assert_eq!(obj.len(), 1);
2215 assert_eq!(obj.get("a").unwrap().as_f64().unwrap() as i64, 1);
2216 }
2217
2218 #[test]
2219 fn test_partition_by_missing_field() {
2220 let runtime = setup_runtime();
2221 let expr = runtime.compile(r#"partition_by(@, `"type"`)"#).unwrap();
2222 let data: serde_json::Value =
2224 serde_json::from_str(r#"[{"type": "a"}, {"name": "no-type"}, {"type": "a"}]"#).unwrap();
2225 let result = expr.search(&data).unwrap();
2226 let arr = result.as_array().unwrap();
2227 assert_eq!(arr.len(), 3);
2229 }
2230
2231 #[test]
2232 fn test_partition_by_all_same() {
2233 let runtime = setup_runtime();
2234 let expr = runtime.compile(r#"partition_by(@, `"type"`)"#).unwrap();
2235 let data: serde_json::Value =
2236 serde_json::from_str(r#"[{"type": "a"}, {"type": "a"}, {"type": "a"}]"#).unwrap();
2237 let result = expr.search(&data).unwrap();
2238 let arr = result.as_array().unwrap();
2239 assert_eq!(arr.len(), 1);
2240 let partition = arr[0].as_array().unwrap();
2241 assert_eq!(partition.len(), 3);
2242 }
2243
2244 #[test]
2245 fn test_interpose_null_separator() {
2246 let runtime = setup_runtime();
2247 let expr = runtime.compile("interpose(@, `null`)").unwrap();
2248 let data = json!([1, 2]);
2249 let result = expr.search(&data).unwrap();
2250 let arr = result.as_array().unwrap();
2251 assert_eq!(arr.len(), 3);
2252 assert_eq!(arr[0].as_f64().unwrap() as i64, 1);
2253 assert!(arr[1].is_null());
2254 assert_eq!(arr[2].as_f64().unwrap() as i64, 2);
2255 }
2256
2257 #[test]
2258 fn test_interpose_object_separator() {
2259 let runtime = setup_runtime();
2260 let expr = runtime.compile(r#"interpose(@, `{"sep": true}`)"#).unwrap();
2261 let data = json!([1, 2]);
2262 let result = expr.search(&data).unwrap();
2263 let arr = result.as_array().unwrap();
2264 assert_eq!(arr.len(), 3);
2265 assert!(arr[1].as_object().is_some());
2266 }
2267
2268 #[test]
2273 fn test_zip_basic() {
2274 let runtime = setup_runtime();
2275 let data: serde_json::Value =
2276 serde_json::from_str(r#"{"a": [1, 2, 3], "b": ["x", "y", "z"]}"#).unwrap();
2277 let expr = runtime.compile("zip(a, b)").unwrap();
2278 let result = expr.search(&data).unwrap();
2279 let arr = result.as_array().unwrap();
2280 assert_eq!(arr.len(), 3);
2281 assert_eq!(arr[0].as_array().unwrap()[0].as_f64().unwrap() as i64, 1);
2282 assert_eq!(arr[0].as_array().unwrap()[1].as_str().unwrap(), "x");
2283 }
2284
2285 #[test]
2286 fn test_zip_unequal_lengths() {
2287 let runtime = setup_runtime();
2288 let data: serde_json::Value =
2289 serde_json::from_str(r#"{"a": [1, 2], "b": ["x", "y", "z"]}"#).unwrap();
2290 let expr = runtime.compile("zip(a, b)").unwrap();
2291 let result = expr.search(&data).unwrap();
2292 let arr = result.as_array().unwrap();
2293 assert_eq!(arr.len(), 2);
2295 }
2296
2297 #[test]
2298 fn test_zip_empty_array() {
2299 let runtime = setup_runtime();
2300 let data: serde_json::Value = serde_json::from_str(r#"{"a": [], "b": [1, 2, 3]}"#).unwrap();
2301 let expr = runtime.compile("zip(a, b)").unwrap();
2302 let result = expr.search(&data).unwrap();
2303 let arr = result.as_array().unwrap();
2304 assert_eq!(arr.len(), 0);
2305 }
2306
2307 #[test]
2308 fn test_zip_with_objects() {
2309 let runtime = setup_runtime();
2310 let data: serde_json::Value =
2311 serde_json::from_str(r#"{"names": ["Alice", "Bob"], "scores": [95, 87]}"#).unwrap();
2312 let expr = runtime.compile("zip(names, scores)").unwrap();
2313 let result = expr.search(&data).unwrap();
2314 let arr = result.as_array().unwrap();
2315 assert_eq!(arr.len(), 2);
2316 assert_eq!(arr[0].as_array().unwrap()[0].as_str().unwrap(), "Alice");
2317 assert_eq!(arr[0].as_array().unwrap()[1].as_f64().unwrap() as i64, 95);
2318 }
2319
2320 #[test]
2325 fn test_chunk_basic() {
2326 let runtime = setup_runtime();
2327 let data = json!([1, 2, 3, 4, 5]);
2328 let expr = runtime.compile("chunk(@, `2`)").unwrap();
2329 let result = expr.search(&data).unwrap();
2330 let arr = result.as_array().unwrap();
2331 assert_eq!(arr.len(), 3); assert_eq!(arr[0].as_array().unwrap().len(), 2);
2333 assert_eq!(arr[2].as_array().unwrap().len(), 1);
2334 }
2335
2336 #[test]
2337 fn test_chunk_exact_fit() {
2338 let runtime = setup_runtime();
2339 let data = json!([1, 2, 3, 4, 5, 6]);
2340 let expr = runtime.compile("chunk(@, `3`)").unwrap();
2341 let result = expr.search(&data).unwrap();
2342 let arr = result.as_array().unwrap();
2343 assert_eq!(arr.len(), 2);
2344 assert_eq!(arr[0].as_array().unwrap().len(), 3);
2345 assert_eq!(arr[1].as_array().unwrap().len(), 3);
2346 }
2347
2348 #[test]
2349 fn test_chunk_size_larger_than_array() {
2350 let runtime = setup_runtime();
2351 let data = json!([1, 2, 3]);
2352 let expr = runtime.compile("chunk(@, `10`)").unwrap();
2353 let result = expr.search(&data).unwrap();
2354 let arr = result.as_array().unwrap();
2355 assert_eq!(arr.len(), 1);
2356 assert_eq!(arr[0].as_array().unwrap().len(), 3);
2357 }
2358
2359 #[test]
2360 fn test_chunk_size_one() {
2361 let runtime = setup_runtime();
2362 let data = json!([1, 2, 3]);
2363 let expr = runtime.compile("chunk(@, `1`)").unwrap();
2364 let result = expr.search(&data).unwrap();
2365 let arr = result.as_array().unwrap();
2366 assert_eq!(arr.len(), 3);
2367 }
2368
2369 #[test]
2370 fn test_chunk_and_process_pipeline() {
2371 let runtime = setup_runtime();
2372 let data = json!([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
2373 let expr = runtime.compile("chunk(@, `3`)").unwrap();
2374 let result = expr.search(&data).unwrap();
2375 let arr = result.as_array().unwrap();
2376 assert_eq!(arr.len(), 4);
2378 }
2379
2380 #[test]
2385 fn test_take_basic() {
2386 let runtime = setup_runtime();
2387 let data = json!([1, 2, 3, 4, 5]);
2388 let expr = runtime.compile("take(@, `3`)").unwrap();
2389 let result = expr.search(&data).unwrap();
2390 let arr = result.as_array().unwrap();
2391 assert_eq!(arr.len(), 3);
2392 assert_eq!(arr[0].as_f64().unwrap() as i64, 1);
2393 assert_eq!(arr[2].as_f64().unwrap() as i64, 3);
2394 }
2395
2396 #[test]
2397 fn test_take_more_than_length() {
2398 let runtime = setup_runtime();
2399 let data = json!([1, 2]);
2400 let expr = runtime.compile("take(@, `10`)").unwrap();
2401 let result = expr.search(&data).unwrap();
2402 let arr = result.as_array().unwrap();
2403 assert_eq!(arr.len(), 2);
2404 }
2405
2406 #[test]
2407 fn test_take_zero() {
2408 let runtime = setup_runtime();
2409 let data = json!([1, 2, 3]);
2410 let expr = runtime.compile("take(@, `0`)").unwrap();
2411 let result = expr.search(&data).unwrap();
2412 let arr = result.as_array().unwrap();
2413 assert_eq!(arr.len(), 0);
2414 }
2415
2416 #[test]
2421 fn test_drop_basic() {
2422 let runtime = setup_runtime();
2423 let data = json!([1, 2, 3, 4, 5]);
2424 let expr = runtime.compile("drop(@, `2`)").unwrap();
2425 let result = expr.search(&data).unwrap();
2426 let arr = result.as_array().unwrap();
2427 assert_eq!(arr.len(), 3);
2428 assert_eq!(arr[0].as_f64().unwrap() as i64, 3);
2429 }
2430
2431 #[test]
2432 fn test_drop_more_than_length() {
2433 let runtime = setup_runtime();
2434 let data = json!([1, 2]);
2435 let expr = runtime.compile("drop(@, `10`)").unwrap();
2436 let result = expr.search(&data).unwrap();
2437 let arr = result.as_array().unwrap();
2438 assert_eq!(arr.len(), 0);
2439 }
2440
2441 #[test]
2442 fn test_drop_zero() {
2443 let runtime = setup_runtime();
2444 let data = json!([1, 2, 3]);
2445 let expr = runtime.compile("drop(@, `0`)").unwrap();
2446 let result = expr.search(&data).unwrap();
2447 let arr = result.as_array().unwrap();
2448 assert_eq!(arr.len(), 3);
2449 }
2450
2451 #[test]
2456 fn test_flatten_deep_basic() {
2457 let runtime = setup_runtime();
2458 let data = json!([[1, 2], [3, 4]]);
2459 let expr = runtime.compile("flatten_deep(@)").unwrap();
2460 let result = expr.search(&data).unwrap();
2461 let arr = result.as_array().unwrap();
2462 assert_eq!(arr.len(), 4);
2463 }
2464
2465 #[test]
2466 fn test_flatten_deep_nested() {
2467 let runtime = setup_runtime();
2468 let data = json!([1, [2, [3, [4, [5]]]]]);
2469 let expr = runtime.compile("flatten_deep(@)").unwrap();
2470 let result = expr.search(&data).unwrap();
2471 let arr = result.as_array().unwrap();
2472 assert_eq!(arr.len(), 5);
2473 assert_eq!(arr[4].as_f64().unwrap() as i64, 5);
2474 }
2475
2476 #[test]
2477 fn test_flatten_deep_already_flat() {
2478 let runtime = setup_runtime();
2479 let data = json!([1, 2, 3]);
2480 let expr = runtime.compile("flatten_deep(@)").unwrap();
2481 let result = expr.search(&data).unwrap();
2482 let arr = result.as_array().unwrap();
2483 assert_eq!(arr.len(), 3);
2484 }
2485
2486 #[test]
2487 fn test_flatten_deep_mixed() {
2488 let runtime = setup_runtime();
2489 let data = json!([1, [2, 3], [[4]], [[[5, 6]]]]);
2490 let expr = runtime.compile("flatten_deep(@)").unwrap();
2491 let result = expr.search(&data).unwrap();
2492 let arr = result.as_array().unwrap();
2493 assert_eq!(arr.len(), 6);
2494 }
2495
2496 #[test]
2501 fn test_compact_basic() {
2502 let runtime = setup_runtime();
2503 let data = json!([1, null, 2, false, 3]);
2504 let expr = runtime.compile("compact(@)").unwrap();
2505 let result = expr.search(&data).unwrap();
2506 let arr = result.as_array().unwrap();
2507 assert_eq!(arr.len(), 3);
2508 }
2509
2510 #[test]
2511 fn test_compact_keeps_zero_and_empty_string() {
2512 let runtime = setup_runtime();
2513 let data = json!([0, "", null, true]);
2514 let expr = runtime.compile("compact(@)").unwrap();
2515 let result = expr.search(&data).unwrap();
2516 let arr = result.as_array().unwrap();
2517 assert_eq!(arr.len(), 3); }
2519
2520 #[test]
2521 fn test_compact_all_falsy() {
2522 let runtime = setup_runtime();
2523 let data = json!([null, false, null]);
2524 let expr = runtime.compile("compact(@)").unwrap();
2525 let result = expr.search(&data).unwrap();
2526 let arr = result.as_array().unwrap();
2527 assert_eq!(arr.len(), 0);
2528 }
2529
2530 #[test]
2535 fn test_index_at_positive() {
2536 let runtime = setup_runtime();
2537 let data = json!(["a", "b", "c", "d"]);
2538 let expr = runtime.compile("index_at(@, `2`)").unwrap();
2539 let result = expr.search(&data).unwrap();
2540 assert_eq!(result.as_str().unwrap(), "c");
2541 }
2542
2543 #[test]
2544 fn test_index_at_negative() {
2545 let runtime = setup_runtime();
2546 let data = json!(["a", "b", "c", "d"]);
2547 let expr = runtime.compile("index_at(@, `-1`)").unwrap();
2548 let result = expr.search(&data).unwrap();
2549 assert_eq!(result.as_str().unwrap(), "d");
2550 }
2551
2552 #[test]
2553 fn test_index_at_negative_second() {
2554 let runtime = setup_runtime();
2555 let data = json!(["a", "b", "c", "d"]);
2556 let expr = runtime.compile("index_at(@, `-2`)").unwrap();
2557 let result = expr.search(&data).unwrap();
2558 assert_eq!(result.as_str().unwrap(), "c");
2559 }
2560
2561 #[test]
2562 fn test_index_at_out_of_bounds() {
2563 let runtime = setup_runtime();
2564 let data = json!(["a", "b", "c"]);
2565 let expr = runtime.compile("index_at(@, `10`)").unwrap();
2566 let result = expr.search(&data).unwrap();
2567 assert!(result.is_null());
2568 }
2569
2570 #[test]
2575 fn test_includes_number() {
2576 let runtime = setup_runtime();
2577 let data = json!([1, 2, 3, 4, 5]);
2578 let expr = runtime.compile("includes(@, `3`)").unwrap();
2579 let result = expr.search(&data).unwrap();
2580 assert!(result.as_bool().unwrap());
2581 }
2582
2583 #[test]
2584 fn test_includes_not_found() {
2585 let runtime = setup_runtime();
2586 let data = json!([1, 2, 3]);
2587 let expr = runtime.compile("includes(@, `10`)").unwrap();
2588 let result = expr.search(&data).unwrap();
2589 assert!(!result.as_bool().unwrap());
2590 }
2591
2592 #[test]
2593 fn test_includes_string() {
2594 let runtime = setup_runtime();
2595 let data = json!(["apple", "banana", "cherry"]);
2596 let expr = runtime.compile(r#"includes(@, `"banana"`)"#).unwrap();
2597 let result = expr.search(&data).unwrap();
2598 assert!(result.as_bool().unwrap());
2599 }
2600
2601 #[test]
2602 fn test_includes_object() {
2603 let runtime = setup_runtime();
2604 let data = json!([{"a": 1}, {"b": 2}]);
2605 let expr = runtime.compile(r#"includes(@, `{"a": 1}`)"#).unwrap();
2606 let result = expr.search(&data).unwrap();
2607 assert!(result.as_bool().unwrap());
2608 }
2609
2610 #[test]
2615 fn test_find_index_found() {
2616 let runtime = setup_runtime();
2617 let data = json!(["a", "b", "c", "d"]);
2618 let expr = runtime.compile(r#"find_index(@, `"c"`)"#).unwrap();
2619 let result = expr.search(&data).unwrap();
2620 assert_eq!(result.as_f64().unwrap() as i64, 2);
2621 }
2622
2623 #[test]
2624 fn test_find_index_not_found() {
2625 let runtime = setup_runtime();
2626 let data = json!(["a", "b", "c"]);
2627 let expr = runtime.compile(r#"find_index(@, `"z"`)"#).unwrap();
2628 let result = expr.search(&data).unwrap();
2629 assert_eq!(result.as_f64().unwrap() as i64, -1);
2630 }
2631
2632 #[test]
2637 fn test_group_by_basic() {
2638 let runtime = setup_runtime();
2639 let data: serde_json::Value = serde_json::from_str(
2640 r#"[{"type": "a", "v": 1}, {"type": "b", "v": 2}, {"type": "a", "v": 3}]"#,
2641 )
2642 .unwrap();
2643 let expr = runtime.compile(r#"group_by(@, `"type"`)"#).unwrap();
2644 let result = expr.search(&data).unwrap();
2645 let obj = result.as_object().unwrap();
2646 assert_eq!(obj.get("a").unwrap().as_array().unwrap().len(), 2);
2647 assert_eq!(obj.get("b").unwrap().as_array().unwrap().len(), 1);
2648 }
2649
2650 #[test]
2655 fn test_index_by_basic() {
2656 let runtime = setup_runtime();
2657 let data: serde_json::Value =
2658 serde_json::from_str(r#"[{"id": 1, "name": "alice"}, {"id": 2, "name": "bob"}]"#)
2659 .unwrap();
2660 let expr = runtime.compile(r#"index_by(@, `"id"`)"#).unwrap();
2661 let result = expr.search(&data).unwrap();
2662 let obj = result.as_object().unwrap();
2663 assert_eq!(obj.len(), 2);
2664 let alice = obj.get("1").unwrap().as_object().unwrap();
2666 assert_eq!(alice.get("name").unwrap().as_str().unwrap(), "alice");
2667 let bob = obj.get("2").unwrap().as_object().unwrap();
2668 assert_eq!(bob.get("name").unwrap().as_str().unwrap(), "bob");
2669 }
2670
2671 #[test]
2672 fn test_index_by_string_key() {
2673 let runtime = setup_runtime();
2674 let data: serde_json::Value = serde_json::from_str(
2675 r#"[{"code": "US", "name": "United States"}, {"code": "UK", "name": "United Kingdom"}]"#,
2676 )
2677 .unwrap();
2678 let expr = runtime.compile(r#"index_by(@, `"code"`)"#).unwrap();
2679 let result = expr.search(&data).unwrap();
2680 let obj = result.as_object().unwrap();
2681 assert_eq!(obj.len(), 2);
2682 let us = obj.get("US").unwrap().as_object().unwrap();
2683 assert_eq!(us.get("name").unwrap().as_str().unwrap(), "United States");
2684 }
2685
2686 #[test]
2687 fn test_index_by_duplicate_keys() {
2688 let runtime = setup_runtime();
2690 let data: serde_json::Value = serde_json::from_str(
2691 r#"[{"type": "a", "v": 1}, {"type": "a", "v": 2}, {"type": "a", "v": 3}]"#,
2692 )
2693 .unwrap();
2694 let expr = runtime.compile(r#"index_by(@, `"type"`)"#).unwrap();
2695 let result = expr.search(&data).unwrap();
2696 let obj = result.as_object().unwrap();
2697 assert_eq!(obj.len(), 1);
2698 let a = obj.get("a").unwrap().as_object().unwrap();
2700 assert_eq!(a.get("v").unwrap().as_f64().unwrap() as i64, 3);
2701 }
2702
2703 #[test]
2704 fn test_index_by_missing_key() {
2705 let runtime = setup_runtime();
2707 let data: serde_json::Value = serde_json::from_str(
2708 r#"[{"id": 1, "name": "alice"}, {"name": "bob"}, {"id": 3, "name": "charlie"}]"#,
2709 )
2710 .unwrap();
2711 let expr = runtime.compile(r#"index_by(@, `"id"`)"#).unwrap();
2712 let result = expr.search(&data).unwrap();
2713 let obj = result.as_object().unwrap();
2714 assert_eq!(obj.len(), 2);
2715 assert!(obj.contains_key("1"));
2716 assert!(obj.contains_key("3"));
2717 assert!(!obj.contains_key("2")); }
2719
2720 #[test]
2721 fn test_index_by_empty_array() {
2722 let runtime = setup_runtime();
2723 let data = json!([]);
2724 let expr = runtime.compile(r#"index_by(@, `"id"`)"#).unwrap();
2725 let result = expr.search(&data).unwrap();
2726 let obj = result.as_object().unwrap();
2727 assert!(obj.is_empty());
2728 }
2729
2730 #[test]
2735 fn test_difference() {
2736 let runtime = setup_runtime();
2737 let data: serde_json::Value =
2738 serde_json::from_str(r#"{"a": [1, 2, 3, 4], "b": [2, 4]}"#).unwrap();
2739 let expr = runtime.compile("difference(a, b)").unwrap();
2740 let result = expr.search(&data).unwrap();
2741 let arr = result.as_array().unwrap();
2742 assert_eq!(arr.len(), 2); }
2744
2745 #[test]
2746 fn test_intersection() {
2747 let runtime = setup_runtime();
2748 let data: serde_json::Value =
2749 serde_json::from_str(r#"{"a": [1, 2, 3], "b": [2, 3, 4]}"#).unwrap();
2750 let expr = runtime.compile("intersection(a, b)").unwrap();
2751 let result = expr.search(&data).unwrap();
2752 let arr = result.as_array().unwrap();
2753 assert_eq!(arr.len(), 2); }
2755
2756 #[test]
2757 fn test_union() {
2758 let runtime = setup_runtime();
2759 let data: serde_json::Value =
2760 serde_json::from_str(r#"{"a": [1, 2], "b": [2, 3]}"#).unwrap();
2761 let expr = runtime.compile("union(a, b)").unwrap();
2762 let result = expr.search(&data).unwrap();
2763 let arr = result.as_array().unwrap();
2764 assert_eq!(arr.len(), 3); }
2766
2767 #[test]
2772 fn test_frequencies_basic() {
2773 let runtime = setup_runtime();
2774 let data = json!(["a", "b", "a", "c", "a", "b"]);
2775 let expr = runtime.compile("frequencies(@)").unwrap();
2776 let result = expr.search(&data).unwrap();
2777 let obj = result.as_object().unwrap();
2778 assert_eq!(obj.get("a").unwrap().as_f64().unwrap() as i64, 3);
2779 assert_eq!(obj.get("b").unwrap().as_f64().unwrap() as i64, 2);
2780 assert_eq!(obj.get("c").unwrap().as_f64().unwrap() as i64, 1);
2781 }
2782
2783 #[test]
2784 fn test_frequencies_numbers() {
2785 let runtime = setup_runtime();
2786 let data = json!([1, 2, 1, 1, 2, 3]);
2787 let expr = runtime.compile("frequencies(@)").unwrap();
2788 let result = expr.search(&data).unwrap();
2789 let obj = result.as_object().unwrap();
2790 assert_eq!(obj.get("1").unwrap().as_f64().unwrap() as i64, 3);
2791 assert_eq!(obj.get("2").unwrap().as_f64().unwrap() as i64, 2);
2792 }
2793
2794 #[test]
2799 fn test_mode_basic() {
2800 let runtime = setup_runtime();
2801 let data = json!([1, 2, 2, 3, 2, 4]);
2802 let expr = runtime.compile("mode(@)").unwrap();
2803 let result = expr.search(&data).unwrap();
2804 assert_eq!(result.as_f64().unwrap() as i64, 2);
2805 }
2806
2807 #[test]
2808 fn test_mode_empty() {
2809 let runtime = setup_runtime();
2810 let data = json!([]);
2811 let expr = runtime.compile("mode(@)").unwrap();
2812 let result = expr.search(&data).unwrap();
2813 assert!(result.is_null());
2814 }
2815
2816 #[test]
2821 fn test_cartesian_basic() {
2822 let runtime = setup_runtime();
2823 let data: serde_json::Value =
2824 serde_json::from_str(r#"{"a": [1, 2], "b": ["x", "y"]}"#).unwrap();
2825 let expr = runtime.compile("cartesian(a, b)").unwrap();
2826 let result = expr.search(&data).unwrap();
2827 let arr = result.as_array().unwrap();
2828 assert_eq!(arr.len(), 4); }
2830
2831 #[test]
2832 fn test_cartesian_empty() {
2833 let runtime = setup_runtime();
2834 let data: serde_json::Value = serde_json::from_str(r#"{"a": [], "b": [1, 2]}"#).unwrap();
2835 let expr = runtime.compile("cartesian(a, b)").unwrap();
2836 let result = expr.search(&data).unwrap();
2837 let arr = result.as_array().unwrap();
2838 assert_eq!(arr.len(), 0);
2839 }
2840
2841 #[test]
2842 fn test_cartesian_n_way_two_arrays() {
2843 let runtime = setup_runtime();
2844 let data = json!([[1, 2], ["a", "b"]]);
2845 let expr = runtime.compile("cartesian(@)").unwrap();
2846 let result = expr.search(&data).unwrap();
2847 let arr = result.as_array().unwrap();
2848 assert_eq!(arr.len(), 4); }
2850
2851 #[test]
2852 fn test_cartesian_n_way_three_arrays() {
2853 let runtime = setup_runtime();
2854 let data = json!([[1, 2], ["a", "b"], [true, false]]);
2855 let expr = runtime.compile("cartesian(@)").unwrap();
2856 let result = expr.search(&data).unwrap();
2857 let arr = result.as_array().unwrap();
2858 assert_eq!(arr.len(), 8); }
2860
2861 #[test]
2862 fn test_cartesian_n_way_single_array() {
2863 let runtime = setup_runtime();
2864 let data = json!([[1, 2, 3]]);
2865 let expr = runtime.compile("cartesian(@)").unwrap();
2866 let result = expr.search(&data).unwrap();
2867 let arr = result.as_array().unwrap();
2868 assert_eq!(arr.len(), 3); }
2870
2871 #[test]
2872 fn test_cartesian_n_way_empty() {
2873 let runtime = setup_runtime();
2874 let data = json!([]);
2875 let expr = runtime.compile("cartesian(@)").unwrap();
2876 let result = expr.search(&data).unwrap();
2877 let arr = result.as_array().unwrap();
2878 assert_eq!(arr.len(), 0);
2879 }
2880
2881 #[test]
2886 fn test_first_empty_array() {
2887 let runtime = setup_runtime();
2888 let data = json!([]);
2889 let expr = runtime.compile("first(@)").unwrap();
2890 let result = expr.search(&data).unwrap();
2891 assert!(result.is_null());
2892 }
2893
2894 #[test]
2895 fn test_last_empty_array() {
2896 let runtime = setup_runtime();
2897 let data = json!([]);
2898 let expr = runtime.compile("last(@)").unwrap();
2899 let result = expr.search(&data).unwrap();
2900 assert!(result.is_null());
2901 }
2902
2903 #[test]
2904 fn test_unique_preserves_order() {
2905 let runtime = setup_runtime();
2906 let data = json!(["c", "a", "b", "a", "c"]);
2907 let expr = runtime.compile("unique(@)").unwrap();
2908 let result = expr.search(&data).unwrap();
2909 let arr = result.as_array().unwrap();
2910 assert_eq!(arr.len(), 3);
2911 assert_eq!(arr[0].as_str().unwrap(), "c");
2912 assert_eq!(arr[1].as_str().unwrap(), "a");
2913 assert_eq!(arr[2].as_str().unwrap(), "b");
2914 }
2915
2916 #[test]
2917 fn test_unique_different_types() {
2918 let runtime = setup_runtime();
2919 let data = json!([1, "1", 1, "1"]);
2920 let expr = runtime.compile("unique(@)").unwrap();
2921 let result = expr.search(&data).unwrap();
2922 let arr = result.as_array().unwrap();
2923 assert_eq!(arr.len(), 2); }
2925
2926 #[test]
2927 fn test_range_with_step() {
2928 let runtime = setup_runtime();
2929 let data = json!(null);
2930 let expr = runtime.compile("range(`1`, `10`, `2`)").unwrap();
2931 let result = expr.search(&data).unwrap();
2932 let arr = result.as_array().unwrap();
2933 assert_eq!(arr.len(), 5); assert_eq!(arr[0].as_f64().unwrap() as i64, 1);
2935 assert_eq!(arr[4].as_f64().unwrap() as i64, 9);
2936 }
2937
2938 #[test]
2939 fn test_range_descending() {
2940 let runtime = setup_runtime();
2941 let data = json!(null);
2942 let expr = runtime.compile("range(`5`, `0`, `-1`)").unwrap();
2943 let result = expr.search(&data).unwrap();
2944 let arr = result.as_array().unwrap();
2945 assert_eq!(arr.len(), 5); assert_eq!(arr[0].as_f64().unwrap() as i64, 5);
2947 assert_eq!(arr[4].as_f64().unwrap() as i64, 1);
2948 }
2949
2950 #[test]
2955 fn test_pipeline_unique_sort() {
2956 let runtime = setup_runtime();
2957 let data = json!(["redis", "database", "redis", "nosql", "database"]);
2958 let expr = runtime.compile("unique(@) | sort(@)").unwrap();
2959 let result = expr.search(&data).unwrap();
2960 let arr = result.as_array().unwrap();
2961 assert_eq!(arr.len(), 3);
2962 assert_eq!(arr[0].as_str().unwrap(), "database");
2963 assert_eq!(arr[1].as_str().unwrap(), "nosql");
2964 assert_eq!(arr[2].as_str().unwrap(), "redis");
2965 }
2966
2967 #[test]
2968 fn test_pipeline_filter_take() {
2969 let runtime = setup_runtime();
2970 let data = json!([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
2971 let expr = runtime.compile("[?@ > `3`] | take(@, `3`)").unwrap();
2972 let result = expr.search(&data).unwrap();
2973 let arr = result.as_array().unwrap();
2974 assert_eq!(arr.len(), 3);
2975 assert_eq!(arr[0].as_f64().unwrap() as i64, 4);
2976 assert_eq!(arr[1].as_f64().unwrap() as i64, 5);
2977 assert_eq!(arr[2].as_f64().unwrap() as i64, 6);
2978 }
2979
2980 #[test]
2981 fn test_pipeline_flatten_unique() {
2982 let runtime = setup_runtime();
2983 let data = json!([[1, 2], [2, 3], [3, 4]]);
2984 let expr = runtime.compile("flatten_deep(@) | unique(@)").unwrap();
2985 let result = expr.search(&data).unwrap();
2986 let arr = result.as_array().unwrap();
2987 assert_eq!(arr.len(), 4); }
2989
2990 #[test]
2991 fn test_large_array_processing() {
2992 let runtime = setup_runtime();
2993 let items: Vec<i32> = (1..=1000).collect();
2995 let json_str = serde_json::to_string(&items).unwrap();
2996 let data: serde_json::Value = serde_json::from_str(&json_str).unwrap();
2997
2998 let expr = runtime.compile("length(@)").unwrap();
2999 let result = expr.search(&data).unwrap();
3000 assert_eq!(result.as_f64().unwrap() as i64, 1000);
3001 }
3002
3003 #[test]
3004 fn test_transpose_basic() {
3005 let runtime = setup_runtime();
3006 let data = json!([[1, 2, 3], [4, 5, 6]]);
3007 let expr = runtime.compile("transpose(@)").unwrap();
3008 let result = expr.search(&data).unwrap();
3009 let arr = result.as_array().unwrap();
3010 assert_eq!(arr.len(), 3);
3011 let col0 = arr[0].as_array().unwrap();
3013 assert_eq!(col0[0].as_f64().unwrap() as i64, 1);
3014 assert_eq!(col0[1].as_f64().unwrap() as i64, 4);
3015 let col1 = arr[1].as_array().unwrap();
3017 assert_eq!(col1[0].as_f64().unwrap() as i64, 2);
3018 assert_eq!(col1[1].as_f64().unwrap() as i64, 5);
3019 }
3020
3021 #[test]
3022 fn test_transpose_empty() {
3023 let runtime = setup_runtime();
3024 let data = json!([]);
3025 let expr = runtime.compile("transpose(@)").unwrap();
3026 let result = expr.search(&data).unwrap();
3027 let arr = result.as_array().unwrap();
3028 assert_eq!(arr.len(), 0);
3029 }
3030
3031 #[test]
3032 fn test_transpose_unequal_rows() {
3033 let runtime = setup_runtime();
3034 let data = json!([[1, 2], [3, 4, 5], [6, 7]]);
3035 let expr = runtime.compile("transpose(@)").unwrap();
3036 let result = expr.search(&data).unwrap();
3037 let arr = result.as_array().unwrap();
3038 assert_eq!(arr.len(), 2);
3040 }
3041
3042 #[test]
3043 fn test_pairwise_basic() {
3044 let runtime = setup_runtime();
3045 let data = json!([1, 2, 3, 4]);
3046 let expr = runtime.compile("pairwise(@)").unwrap();
3047 let result = expr.search(&data).unwrap();
3048 let arr = result.as_array().unwrap();
3049 assert_eq!(arr.len(), 3);
3050 let pair0 = arr[0].as_array().unwrap();
3052 assert_eq!(pair0[0].as_f64().unwrap() as i64, 1);
3053 assert_eq!(pair0[1].as_f64().unwrap() as i64, 2);
3054 let pair1 = arr[1].as_array().unwrap();
3056 assert_eq!(pair1[0].as_f64().unwrap() as i64, 2);
3057 assert_eq!(pair1[1].as_f64().unwrap() as i64, 3);
3058 }
3059
3060 #[test]
3061 fn test_pairwise_short_array() {
3062 let runtime = setup_runtime();
3063 let data = json!([1]);
3064 let expr = runtime.compile("pairwise(@)").unwrap();
3065 let result = expr.search(&data).unwrap();
3066 let arr = result.as_array().unwrap();
3067 assert_eq!(arr.len(), 0);
3068 }
3069
3070 #[test]
3071 fn test_sliding_window_alias() {
3072 let runtime = setup_runtime();
3073 let data = json!([1, 2, 3, 4, 5]);
3074 let expr = runtime.compile("sliding_window(@, `3`)").unwrap();
3075 let result = expr.search(&data).unwrap();
3076 let arr = result.as_array().unwrap();
3077 assert_eq!(arr.len(), 3);
3078 let win0 = arr[0].as_array().unwrap();
3080 assert_eq!(win0.len(), 3);
3081 assert_eq!(win0[0].as_f64().unwrap() as i64, 1);
3082 }
3083
3084 #[test]
3086 fn test_indices_array_found() {
3087 let runtime = setup_runtime();
3088 let data = json!([1, 2, 3, 2, 4, 2]);
3089 let expr = runtime.compile("indices_array(@, `2`)").unwrap();
3090 let result = expr.search(&data).unwrap();
3091 let arr = result.as_array().unwrap();
3092 assert_eq!(arr.len(), 3);
3093 assert_eq!(arr[0].as_f64().unwrap() as i64, 1);
3094 assert_eq!(arr[1].as_f64().unwrap() as i64, 3);
3095 assert_eq!(arr[2].as_f64().unwrap() as i64, 5);
3096 }
3097
3098 #[test]
3099 fn test_indices_array_not_found() {
3100 let runtime = setup_runtime();
3101 let data = json!([1, 2, 3]);
3102 let expr = runtime.compile("indices_array(@, `5`)").unwrap();
3103 let result = expr.search(&data).unwrap();
3104 let arr = result.as_array().unwrap();
3105 assert_eq!(arr.len(), 0);
3106 }
3107
3108 #[test]
3109 fn test_indices_array_strings() {
3110 let runtime = setup_runtime();
3111 let data = json!(["a", "b", "a", "c", "a"]);
3112 let expr = runtime.compile(r#"indices_array(@, `"a"`)"#).unwrap();
3113 let result = expr.search(&data).unwrap();
3114 let arr = result.as_array().unwrap();
3115 assert_eq!(arr.len(), 3);
3116 assert_eq!(arr[0].as_f64().unwrap() as i64, 0);
3117 assert_eq!(arr[1].as_f64().unwrap() as i64, 2);
3118 assert_eq!(arr[2].as_f64().unwrap() as i64, 4);
3119 }
3120
3121 #[test]
3123 fn test_inside_array_true() {
3124 let runtime = setup_runtime();
3125 let data: serde_json::Value =
3126 serde_json::from_str(r#"{"a": [1, 2], "b": [1, 2, 3, 4]}"#).unwrap();
3127 let expr = runtime.compile("inside_array(a, b)").unwrap();
3128 let result = expr.search(&data).unwrap();
3129 assert!(result.as_bool().unwrap());
3130 }
3131
3132 #[test]
3133 fn test_inside_array_false() {
3134 let runtime = setup_runtime();
3135 let data: serde_json::Value =
3136 serde_json::from_str(r#"{"a": [1, 5], "b": [1, 2, 3, 4]}"#).unwrap();
3137 let expr = runtime.compile("inside_array(a, b)").unwrap();
3138 let result = expr.search(&data).unwrap();
3139 assert!(!result.as_bool().unwrap());
3140 }
3141
3142 #[test]
3143 fn test_inside_array_empty() {
3144 let runtime = setup_runtime();
3145 let data: serde_json::Value = serde_json::from_str(r#"{"a": [], "b": [1, 2, 3]}"#).unwrap();
3146 let expr = runtime.compile("inside_array(a, b)").unwrap();
3147 let result = expr.search(&data).unwrap();
3148 assert!(result.as_bool().unwrap());
3149 }
3150
3151 #[test]
3153 fn test_bsearch_found() {
3154 let runtime = setup_runtime();
3155 let data = json!([1, 3, 5, 7, 9]);
3156 let expr = runtime.compile("bsearch(@, `5`)").unwrap();
3157 let result = expr.search(&data).unwrap();
3158 assert_eq!(result.as_f64().unwrap() as i64, 2);
3159 }
3160
3161 #[test]
3162 fn test_bsearch_not_found_middle() {
3163 let runtime = setup_runtime();
3164 let data = json!([1, 3, 5, 7, 9]);
3165 let expr = runtime.compile("bsearch(@, `4`)").unwrap();
3166 let result = expr.search(&data).unwrap();
3167 assert_eq!(result.as_f64().unwrap() as i64, -3);
3168 }
3169
3170 #[test]
3171 fn test_bsearch_not_found_start() {
3172 let runtime = setup_runtime();
3173 let data = json!([1, 3, 5, 7, 9]);
3174 let expr = runtime.compile("bsearch(@, `0`)").unwrap();
3175 let result = expr.search(&data).unwrap();
3176 assert_eq!(result.as_f64().unwrap() as i64, -1);
3177 }
3178
3179 #[test]
3180 fn test_bsearch_not_found_end() {
3181 let runtime = setup_runtime();
3182 let data = json!([1, 3, 5, 7, 9]);
3183 let expr = runtime.compile("bsearch(@, `10`)").unwrap();
3184 let result = expr.search(&data).unwrap();
3185 assert_eq!(result.as_f64().unwrap() as i64, -6);
3186 }
3187
3188 #[test]
3189 fn test_bsearch_empty_array() {
3190 let runtime = setup_runtime();
3191 let data = json!([]);
3192 let expr = runtime.compile("bsearch(@, `5`)").unwrap();
3193 let result = expr.search(&data).unwrap();
3194 assert_eq!(result.as_f64().unwrap() as i64, -1);
3195 }
3196
3197 #[test]
3199 fn test_repeat_array_basic() {
3200 let runtime = setup_runtime();
3201 let data = json!(null);
3202 let expr = runtime.compile("repeat_array(`1`, `3`)").unwrap();
3203 let result = expr.search(&data).unwrap();
3204 let arr = result.as_array().unwrap();
3205 assert_eq!(arr.len(), 3);
3206 assert_eq!(arr[0].as_f64().unwrap() as i64, 1);
3207 assert_eq!(arr[1].as_f64().unwrap() as i64, 1);
3208 assert_eq!(arr[2].as_f64().unwrap() as i64, 1);
3209 }
3210
3211 #[test]
3212 fn test_repeat_array_string() {
3213 let runtime = setup_runtime();
3214 let data = json!(null);
3215 let expr = runtime.compile(r#"repeat_array(`"x"`, `4`)"#).unwrap();
3216 let result = expr.search(&data).unwrap();
3217 let arr = result.as_array().unwrap();
3218 assert_eq!(arr.len(), 4);
3219 assert_eq!(arr[0].as_str().unwrap(), "x");
3220 assert_eq!(arr[3].as_str().unwrap(), "x");
3221 }
3222
3223 #[test]
3224 fn test_repeat_array_zero() {
3225 let runtime = setup_runtime();
3226 let data = json!(null);
3227 let expr = runtime.compile("repeat_array(`1`, `0`)").unwrap();
3228 let result = expr.search(&data).unwrap();
3229 let arr = result.as_array().unwrap();
3230 assert_eq!(arr.len(), 0);
3231 }
3232
3233 #[test]
3234 fn test_repeat_array_object() {
3235 let runtime = setup_runtime();
3236 let data = json!(null);
3237 let expr = runtime.compile(r#"repeat_array(`{"a": 1}`, `2`)"#).unwrap();
3238 let result = expr.search(&data).unwrap();
3239 let arr = result.as_array().unwrap();
3240 assert_eq!(arr.len(), 2);
3241 assert_eq!(
3242 arr[0]
3243 .as_object()
3244 .unwrap()
3245 .get("a")
3246 .unwrap()
3247 .as_f64()
3248 .unwrap() as i64,
3249 1
3250 );
3251 }
3252
3253 #[test]
3255 fn test_cycle_basic() {
3256 let runtime = setup_runtime();
3257 let data = json!([1, 2, 3]);
3258 let expr = runtime.compile("cycle(@, `2`)").unwrap();
3259 let result = expr.search(&data).unwrap();
3260 let arr = result.as_array().unwrap();
3261 assert_eq!(arr.len(), 6);
3262 assert_eq!(arr[0].as_f64().unwrap() as i64, 1);
3263 assert_eq!(arr[1].as_f64().unwrap() as i64, 2);
3264 assert_eq!(arr[2].as_f64().unwrap() as i64, 3);
3265 assert_eq!(arr[3].as_f64().unwrap() as i64, 1);
3266 assert_eq!(arr[4].as_f64().unwrap() as i64, 2);
3267 assert_eq!(arr[5].as_f64().unwrap() as i64, 3);
3268 }
3269
3270 #[test]
3271 fn test_cycle_strings() {
3272 let runtime = setup_runtime();
3273 let data = json!(["a", "b"]);
3274 let expr = runtime.compile("cycle(@, `3`)").unwrap();
3275 let result = expr.search(&data).unwrap();
3276 let arr = result.as_array().unwrap();
3277 assert_eq!(arr.len(), 6);
3278 assert_eq!(arr[0].as_str().unwrap(), "a");
3279 assert_eq!(arr[1].as_str().unwrap(), "b");
3280 assert_eq!(arr[2].as_str().unwrap(), "a");
3281 }
3282
3283 #[test]
3284 fn test_cycle_zero() {
3285 let runtime = setup_runtime();
3286 let data = json!([1, 2, 3]);
3287 let expr = runtime.compile("cycle(@, `0`)").unwrap();
3288 let result = expr.search(&data).unwrap();
3289 let arr = result.as_array().unwrap();
3290 assert_eq!(arr.len(), 0);
3291 }
3292
3293 #[test]
3294 fn test_cycle_empty_array() {
3295 let runtime = setup_runtime();
3296 let data = json!([]);
3297 let expr = runtime.compile("cycle(@, `5`)").unwrap();
3298 let result = expr.search(&data).unwrap();
3299 let arr = result.as_array().unwrap();
3300 assert_eq!(arr.len(), 0);
3301 }
3302
3303 #[test]
3304 fn test_cycle_once() {
3305 let runtime = setup_runtime();
3306 let data = json!([1, 2]);
3307 let expr = runtime.compile("cycle(@, `1`)").unwrap();
3308 let result = expr.search(&data).unwrap();
3309 let arr = result.as_array().unwrap();
3310 assert_eq!(arr.len(), 2);
3311 assert_eq!(arr[0].as_f64().unwrap() as i64, 1);
3312 assert_eq!(arr[1].as_f64().unwrap() as i64, 2);
3313 }
3314
3315 #[test]
3316 fn test_lag_by_one() {
3317 let runtime = setup_runtime();
3318 let data = json!([1, 2, 3]);
3319 let expr = runtime.compile("lag(@, `1`)").unwrap();
3320 let result = expr.search(&data).unwrap();
3321 assert_eq!(result, json!([null, 1, 2]));
3322 }
3323
3324 #[test]
3325 fn test_lag_by_two() {
3326 let runtime = setup_runtime();
3327 let data = json!([1, 2, 3]);
3328 let expr = runtime.compile("lag(@, `2`)").unwrap();
3329 let result = expr.search(&data).unwrap();
3330 assert_eq!(result, json!([null, null, 1]));
3331 }
3332
3333 #[test]
3334 fn test_lag_by_zero() {
3335 let runtime = setup_runtime();
3336 let data = json!([1, 2, 3]);
3337 let expr = runtime.compile("lag(@, `0`)").unwrap();
3338 let result = expr.search(&data).unwrap();
3339 assert_eq!(result, json!([1, 2, 3]));
3340 }
3341
3342 #[test]
3343 fn test_lag_exceeds_length() {
3344 let runtime = setup_runtime();
3345 let data = json!([1, 2, 3]);
3346 let expr = runtime.compile("lag(@, `5`)").unwrap();
3347 let result = expr.search(&data).unwrap();
3348 assert_eq!(result, json!([null, null, null]));
3349 }
3350
3351 #[test]
3352 fn test_lag_empty_array() {
3353 let runtime = setup_runtime();
3354 let data = json!([]);
3355 let expr = runtime.compile("lag(@, `1`)").unwrap();
3356 let result = expr.search(&data).unwrap();
3357 assert_eq!(result, json!([]));
3358 }
3359
3360 #[test]
3361 fn test_lead_by_one() {
3362 let runtime = setup_runtime();
3363 let data = json!([1, 2, 3]);
3364 let expr = runtime.compile("lead(@, `1`)").unwrap();
3365 let result = expr.search(&data).unwrap();
3366 assert_eq!(result, json!([2, 3, null]));
3367 }
3368
3369 #[test]
3370 fn test_lead_by_two() {
3371 let runtime = setup_runtime();
3372 let data = json!([1, 2, 3]);
3373 let expr = runtime.compile("lead(@, `2`)").unwrap();
3374 let result = expr.search(&data).unwrap();
3375 assert_eq!(result, json!([3, null, null]));
3376 }
3377
3378 #[test]
3379 fn test_lead_by_zero() {
3380 let runtime = setup_runtime();
3381 let data = json!([1, 2, 3]);
3382 let expr = runtime.compile("lead(@, `0`)").unwrap();
3383 let result = expr.search(&data).unwrap();
3384 assert_eq!(result, json!([1, 2, 3]));
3385 }
3386
3387 #[test]
3388 fn test_lead_exceeds_length() {
3389 let runtime = setup_runtime();
3390 let data = json!([1, 2, 3]);
3391 let expr = runtime.compile("lead(@, `5`)").unwrap();
3392 let result = expr.search(&data).unwrap();
3393 assert_eq!(result, json!([null, null, null]));
3394 }
3395
3396 #[test]
3397 fn test_lead_empty_array() {
3398 let runtime = setup_runtime();
3399 let data = json!([]);
3400 let expr = runtime.compile("lead(@, `1`)").unwrap();
3401 let result = expr.search(&data).unwrap();
3402 assert_eq!(result, json!([]));
3403 }
3404}