1use super::types::*;
2use crate::error::PickError;
3use serde_json::Value;
4
5const MAX_EXTRACT_RESULTS: usize = 1_000_000;
6
7pub fn execute(value: &Value, expression: &Expression) -> Result<Vec<Value>, PickError> {
14 let single = expression.pipelines.len() == 1;
15 let mut all_results = Vec::new();
16
17 for pipeline in &expression.pipelines {
18 match execute_pipeline(value, pipeline) {
19 Ok(results) => all_results.extend(results),
20 Err(e) if !single => {
21 if !matches!(e, PickError::KeyNotFound(_)) {
23 return Err(e);
24 }
25 }
26 Err(e) => return Err(e),
27 }
28 }
29
30 Ok(all_results)
31}
32
33pub fn execute_pipeline(value: &Value, pipeline: &Pipeline) -> Result<Vec<Value>, PickError> {
35 let mut current = vec![value.clone()];
36
37 for stage in &pipeline.stages {
38 current = execute_stage(¤t, stage)?;
39 }
40
41 Ok(current)
42}
43
44fn execute_stage(inputs: &[Value], stage: &PipeStage) -> Result<Vec<Value>, PickError> {
45 match stage {
46 PipeStage::Path(selector) => {
47 let mut results = Vec::new();
48 for input in inputs {
49 results.extend(extract(input, selector)?);
50 }
51 Ok(results)
52 }
53 PipeStage::Builtin(builtin) => {
54 let mut results = Vec::new();
55 for input in inputs {
56 results.push(apply_builtin(builtin, input)?);
57 }
58 Ok(results)
59 }
60 PipeStage::Select(filter) => {
61 let mut results = Vec::new();
62 for input in inputs {
63 if super::filter::evaluate(input, filter)? {
64 results.push(input.clone());
65 }
66 }
67 Ok(results)
68 }
69 PipeStage::Set { path, value } => {
70 let json_value = value.to_json_value();
71 let mut results = Vec::new();
72 for input in inputs {
73 results.push(super::manipulate::apply_set(
74 input,
75 &path.segments,
76 &json_value,
77 )?);
78 }
79 Ok(results)
80 }
81 PipeStage::Del(path) => {
82 let mut results = Vec::new();
83 for input in inputs {
84 results.push(super::manipulate::apply_del(input, &path.segments)?);
85 }
86 Ok(results)
87 }
88 }
89}
90
91pub fn extract(value: &Value, selector: &Selector) -> Result<Vec<Value>, PickError> {
97 if selector.segments.is_empty() {
98 return Ok(vec![value.clone()]);
99 }
100
101 let mut current = vec![value.clone()];
102
103 for segment in &selector.segments {
104 let mut next = Vec::new();
105
106 for val in ¤t {
107 let keyed = resolve_key(val, segment)?;
108 let indexed = apply_indices(keyed, &segment.indices)?;
109 let final_values = apply_segment_builtin(&segment.builtin, indexed)?;
110
111 next.extend(final_values);
112 if next.len() > MAX_EXTRACT_RESULTS {
113 return Err(PickError::TooManyResults(MAX_EXTRACT_RESULTS));
114 }
115 }
116
117 current = next;
118 }
119
120 Ok(current)
121}
122
123fn resolve_key(value: &Value, segment: &Segment) -> Result<Vec<Value>, PickError> {
128 if segment.key.is_none() && segment.builtin.is_some() {
130 return Ok(vec![value.clone()]);
131 }
132
133 if segment.recursive {
134 resolve_key_recursive(value, segment)
135 } else {
136 resolve_key_direct(value, segment)
137 }
138}
139
140fn resolve_key_direct(value: &Value, segment: &Segment) -> Result<Vec<Value>, PickError> {
141 if let Some(ref key) = segment.key {
142 match value {
143 Value::Object(map) => match map.get(key) {
144 Some(v) => Ok(vec![v.clone()]),
145 None => Err(PickError::KeyNotFound(key.clone())),
146 },
147 other => Err(PickError::NotAnObject(
148 key.clone(),
149 value_type_name(other).into(),
150 )),
151 }
152 } else {
153 Ok(vec![value.clone()])
155 }
156}
157
158fn resolve_key_recursive(value: &Value, segment: &Segment) -> Result<Vec<Value>, PickError> {
159 let key = segment
160 .key
161 .as_ref()
162 .ok_or_else(|| PickError::InvalidSelector("recursive descent requires a key".into()))?;
163
164 let found = recursive_find(value, key);
165 if found.is_empty() {
166 return Err(PickError::KeyNotFound(key.clone()));
167 }
168 Ok(found)
169}
170
171fn recursive_find(value: &Value, key: &str) -> Vec<Value> {
174 let mut results = Vec::new();
175 recursive_find_inner(value, key, &mut results);
176 results
177}
178
179fn recursive_find_inner(value: &Value, key: &str, results: &mut Vec<Value>) {
180 match value {
181 Value::Object(map) => {
182 if let Some(v) = map.get(key) {
183 results.push(v.clone());
184 }
185 for v in map.values() {
186 recursive_find_inner(v, key, results);
187 }
188 }
189 Value::Array(arr) => {
190 for item in arr {
191 recursive_find_inner(item, key, results);
192 }
193 }
194 _ => {}
195 }
196}
197
198fn apply_indices(values: Vec<Value>, indices: &[Index]) -> Result<Vec<Value>, PickError> {
203 let mut current = values;
204
205 for index in indices {
206 let mut next = Vec::new();
207 for v in ¤t {
208 match index {
209 Index::Number(n) => {
210 apply_number_index(v, *n, &mut next)?;
211 }
212 Index::Wildcard => {
213 apply_wildcard(v, &mut next)?;
214 }
215 Index::Slice { start, end } => {
216 apply_slice(v, *start, *end, &mut next)?;
217 }
218 }
219 }
220 current = next;
221 }
222
223 Ok(current)
224}
225
226fn apply_number_index(value: &Value, n: i64, out: &mut Vec<Value>) -> Result<(), PickError> {
227 match value {
228 Value::Array(arr) => {
229 let i = resolve_array_index(n, arr.len())?;
230 match arr.get(i) {
231 Some(elem) => {
232 out.push(elem.clone());
233 Ok(())
234 }
235 None => Err(PickError::IndexOutOfBounds(n)),
236 }
237 }
238 other => Err(PickError::NotAnArray(value_type_name(other).into())),
239 }
240}
241
242fn apply_wildcard(value: &Value, out: &mut Vec<Value>) -> Result<(), PickError> {
243 match value {
244 Value::Array(arr) => {
245 out.extend(arr.iter().cloned());
246 Ok(())
247 }
248 other => Err(PickError::NotAnArray(value_type_name(other).into())),
249 }
250}
251
252fn apply_slice(
256 value: &Value,
257 start: Option<i64>,
258 end: Option<i64>,
259 out: &mut Vec<Value>,
260) -> Result<(), PickError> {
261 match value {
262 Value::Array(arr) => {
263 let len = arr.len() as i64;
264 let s = resolve_slice_bound(start, 0, len);
265 let e = resolve_slice_bound(end, len, len);
266 let s = s.clamp(0, len) as usize;
267 let e = e.clamp(0, len) as usize;
268 if s < e {
269 out.extend(arr[s..e].iter().cloned());
270 }
271 Ok(())
272 }
273 other => Err(PickError::NotAnArray(value_type_name(other).into())),
274 }
275}
276
277fn resolve_array_index(n: i64, len: usize) -> Result<usize, PickError> {
278 let len_i64 = i64::try_from(len).map_err(|_| PickError::IndexOutOfBounds(n))?;
279 if n < 0 {
280 if n.unsigned_abs() > len as u64 {
281 return Err(PickError::IndexOutOfBounds(n));
282 }
283 Ok((len_i64 + n) as usize)
284 } else {
285 Ok(n as usize)
286 }
287}
288
289fn resolve_slice_bound(bound: Option<i64>, default: i64, len: i64) -> i64 {
291 match bound {
292 None => default,
293 Some(i) if i < 0 => (len + i).max(0),
294 Some(i) => i,
295 }
296}
297
298fn apply_segment_builtin(
303 builtin: &Option<Builtin>,
304 values: Vec<Value>,
305) -> Result<Vec<Value>, PickError> {
306 match builtin {
307 None => Ok(values),
308 Some(b) => values.into_iter().map(|v| apply_builtin(b, &v)).collect(),
309 }
310}
311
312pub fn apply_builtin(builtin: &Builtin, value: &Value) -> Result<Value, PickError> {
313 match builtin {
314 Builtin::Keys => match value {
315 Value::Object(map) => Ok(Value::Array(
316 map.keys().map(|k| Value::String(k.clone())).collect(),
317 )),
318 Value::Array(arr) => Ok(Value::Array(
319 (0..arr.len())
320 .map(|i| Value::Number(serde_json::Number::from(i)))
321 .collect(),
322 )),
323 other => Err(PickError::InvalidSelector(format!(
324 "keys() requires object or array, got {}",
325 value_type_name(other)
326 ))),
327 },
328 Builtin::Values => match value {
329 Value::Object(map) => Ok(Value::Array(map.values().cloned().collect())),
330 Value::Array(_) => Ok(value.clone()),
331 other => Err(PickError::InvalidSelector(format!(
332 "values() requires object or array, got {}",
333 value_type_name(other)
334 ))),
335 },
336 Builtin::Length => match value {
337 Value::Array(arr) => Ok(Value::Number(arr.len().into())),
338 Value::Object(map) => Ok(Value::Number(map.len().into())),
339 Value::String(s) => Ok(Value::Number(s.len().into())),
340 Value::Null => Ok(Value::Number(0.into())),
341 other => Err(PickError::InvalidSelector(format!(
342 "length() requires array, object, or string, got {}",
343 value_type_name(other)
344 ))),
345 },
346 }
347}
348
349pub fn value_type_name(v: &Value) -> &'static str {
354 match v {
355 Value::Null => "null",
356 Value::Bool(_) => "boolean",
357 Value::Number(_) => "number",
358 Value::String(_) => "string",
359 Value::Array(_) => "array",
360 Value::Object(_) => "object",
361 }
362}
363
364#[cfg(test)]
369mod tests {
370 use super::*;
371 use serde_json::json;
372
373 #[test]
376 fn extract_empty_selector() {
377 let val = json!({"a": 1});
378 let sel = Selector::parse("").unwrap();
379 let result = extract(&val, &sel).unwrap();
380 assert_eq!(result, vec![json!({"a": 1})]);
381 }
382
383 #[test]
384 fn extract_simple_key() {
385 let val = json!({"name": "Alice"});
386 let sel = Selector::parse("name").unwrap();
387 let result = extract(&val, &sel).unwrap();
388 assert_eq!(result, vec![json!("Alice")]);
389 }
390
391 #[test]
392 fn extract_nested_key() {
393 let val = json!({"foo": {"bar": 42}});
394 let sel = Selector::parse("foo.bar").unwrap();
395 let result = extract(&val, &sel).unwrap();
396 assert_eq!(result, vec![json!(42)]);
397 }
398
399 #[test]
400 fn extract_array_index() {
401 let val = json!({"items": [10, 20, 30]});
402 let sel = Selector::parse("items[1]").unwrap();
403 let result = extract(&val, &sel).unwrap();
404 assert_eq!(result, vec![json!(20)]);
405 }
406
407 #[test]
408 fn extract_negative_index() {
409 let val = json!({"items": [10, 20, 30]});
410 let sel = Selector::parse("items[-1]").unwrap();
411 let result = extract(&val, &sel).unwrap();
412 assert_eq!(result, vec![json!(30)]);
413 }
414
415 #[test]
416 fn extract_negative_index_first() {
417 let val = json!({"items": [10, 20, 30]});
418 let sel = Selector::parse("items[-3]").unwrap();
419 let result = extract(&val, &sel).unwrap();
420 assert_eq!(result, vec![json!(10)]);
421 }
422
423 #[test]
424 fn extract_wildcard() {
425 let val = json!({"items": [{"name": "a"}, {"name": "b"}]});
426 let sel = Selector::parse("items[*].name").unwrap();
427 let result = extract(&val, &sel).unwrap();
428 assert_eq!(result, vec![json!("a"), json!("b")]);
429 }
430
431 #[test]
432 fn extract_chained_indices() {
433 let val = json!({"matrix": [[1, 2], [3, 4]]});
434 let sel = Selector::parse("matrix[0][1]").unwrap();
435 let result = extract(&val, &sel).unwrap();
436 assert_eq!(result, vec![json!(2)]);
437 }
438
439 #[test]
440 fn extract_leading_index() {
441 let val = json!([{"name": "first"}, {"name": "second"}]);
442 let sel = Selector::parse("[0].name").unwrap();
443 let result = extract(&val, &sel).unwrap();
444 assert_eq!(result, vec![json!("first")]);
445 }
446
447 #[test]
448 fn extract_key_not_found() {
449 let val = json!({"a": 1});
450 let sel = Selector::parse("b").unwrap();
451 assert!(extract(&val, &sel).is_err());
452 }
453
454 #[test]
455 fn extract_index_out_of_bounds() {
456 let val = json!({"items": [1, 2]});
457 let sel = Selector::parse("items[5]").unwrap();
458 assert!(extract(&val, &sel).is_err());
459 }
460
461 #[test]
462 fn extract_negative_index_out_of_bounds() {
463 let val = json!({"items": [1, 2]});
464 let sel = Selector::parse("items[-5]").unwrap();
465 assert!(extract(&val, &sel).is_err());
466 }
467
468 #[test]
469 fn extract_not_an_object() {
470 let val = json!("hello");
471 let sel = Selector::parse("foo").unwrap();
472 assert!(extract(&val, &sel).is_err());
473 }
474
475 #[test]
476 fn extract_not_an_array() {
477 let val = json!({"foo": "bar"});
478 let sel = Selector::parse("foo[0]").unwrap();
479 assert!(extract(&val, &sel).is_err());
480 }
481
482 #[test]
483 fn extract_wildcard_on_non_array() {
484 let val = json!({"foo": "bar"});
485 let sel = Selector::parse("foo[*]").unwrap();
486 assert!(extract(&val, &sel).is_err());
487 }
488
489 #[test]
490 fn extract_null_value() {
491 let val = json!({"foo": null});
492 let sel = Selector::parse("foo").unwrap();
493 let result = extract(&val, &sel).unwrap();
494 assert_eq!(result, vec![Value::Null]);
495 }
496
497 #[test]
498 fn extract_boolean() {
499 let val = json!({"active": true});
500 let sel = Selector::parse("active").unwrap();
501 let result = extract(&val, &sel).unwrap();
502 assert_eq!(result, vec![json!(true)]);
503 }
504
505 #[test]
506 fn extract_nested_array_wildcard() {
507 let val = json!([{"items": [1, 2]}, {"items": [3, 4]}]);
508 let sel = Selector::parse("[*].items[0]").unwrap();
509 let result = extract(&val, &sel).unwrap();
510 assert_eq!(result, vec![json!(1), json!(3)]);
511 }
512
513 #[test]
514 fn extract_deep_nesting() {
515 let val = json!({"a": {"b": {"c": {"d": 99}}}});
516 let sel = Selector::parse("a.b.c.d").unwrap();
517 let result = extract(&val, &sel).unwrap();
518 assert_eq!(result, vec![json!(99)]);
519 }
520
521 #[test]
522 fn extract_key_on_null() {
523 let val = json!({"a": null});
524 let sel = Selector::parse("a.b").unwrap();
525 assert!(extract(&val, &sel).is_err());
526 }
527
528 #[test]
529 fn extract_quoted_key_with_dot() {
530 let val = json!({"foo.bar": {"baz": 1}});
531 let sel = Selector::parse("\"foo.bar\".baz").unwrap();
532 let result = extract(&val, &sel).unwrap();
533 assert_eq!(result, vec![json!(1)]);
534 }
535
536 #[test]
537 fn extract_hyphenated_key() {
538 let val = json!({"content-type": "text/html"});
539 let sel = Selector::parse("content-type").unwrap();
540 let result = extract(&val, &sel).unwrap();
541 assert_eq!(result, vec![json!("text/html")]);
542 }
543
544 #[test]
545 fn extract_empty_array_wildcard() {
546 let val = json!({"items": []});
547 let sel = Selector::parse("items[*]").unwrap();
548 let result = extract(&val, &sel).unwrap();
549 assert!(result.is_empty());
550 }
551
552 #[test]
555 fn extract_slice_full() {
556 let val = json!({"items": [10, 20, 30, 40, 50]});
557 let sel = Selector::parse("items[1:3]").unwrap();
558 let result = extract(&val, &sel).unwrap();
559 assert_eq!(result, vec![json!(20), json!(30)]);
560 }
561
562 #[test]
563 fn extract_slice_from_start() {
564 let val = json!({"items": [10, 20, 30, 40, 50]});
565 let sel = Selector::parse("items[:2]").unwrap();
566 let result = extract(&val, &sel).unwrap();
567 assert_eq!(result, vec![json!(10), json!(20)]);
568 }
569
570 #[test]
571 fn extract_slice_to_end() {
572 let val = json!({"items": [10, 20, 30, 40, 50]});
573 let sel = Selector::parse("items[3:]").unwrap();
574 let result = extract(&val, &sel).unwrap();
575 assert_eq!(result, vec![json!(40), json!(50)]);
576 }
577
578 #[test]
579 fn extract_slice_all() {
580 let val = json!({"items": [10, 20, 30]});
581 let sel = Selector::parse("items[:]").unwrap();
582 let result = extract(&val, &sel).unwrap();
583 assert_eq!(result, vec![json!(10), json!(20), json!(30)]);
584 }
585
586 #[test]
587 fn extract_slice_negative_start() {
588 let val = json!({"items": [10, 20, 30, 40, 50]});
589 let sel = Selector::parse("items[-2:]").unwrap();
590 let result = extract(&val, &sel).unwrap();
591 assert_eq!(result, vec![json!(40), json!(50)]);
592 }
593
594 #[test]
595 fn extract_slice_negative_end() {
596 let val = json!({"items": [10, 20, 30, 40, 50]});
597 let sel = Selector::parse("items[:-2]").unwrap();
598 let result = extract(&val, &sel).unwrap();
599 assert_eq!(result, vec![json!(10), json!(20), json!(30)]);
600 }
601
602 #[test]
603 fn extract_slice_both_negative() {
604 let val = json!({"items": [10, 20, 30, 40, 50]});
605 let sel = Selector::parse("items[-3:-1]").unwrap();
606 let result = extract(&val, &sel).unwrap();
607 assert_eq!(result, vec![json!(30), json!(40)]);
608 }
609
610 #[test]
611 fn extract_slice_empty_result() {
612 let val = json!({"items": [10, 20, 30]});
613 let sel = Selector::parse("items[5:10]").unwrap();
614 let result = extract(&val, &sel).unwrap();
615 assert!(result.is_empty());
616 }
617
618 #[test]
619 fn extract_slice_reversed_bounds_empty() {
620 let val = json!({"items": [10, 20, 30]});
621 let sel = Selector::parse("items[3:1]").unwrap();
622 let result = extract(&val, &sel).unwrap();
623 assert!(result.is_empty());
624 }
625
626 #[test]
627 fn extract_slice_on_non_array() {
628 let val = json!({"items": "hello"});
629 let sel = Selector::parse("items[0:2]").unwrap();
630 assert!(extract(&val, &sel).is_err());
631 }
632
633 #[test]
634 fn extract_slice_clamped_end() {
635 let val = json!({"items": [10, 20, 30]});
637 let sel = Selector::parse("items[1:100]").unwrap();
638 let result = extract(&val, &sel).unwrap();
639 assert_eq!(result, vec![json!(20), json!(30)]);
640 }
641
642 #[test]
643 fn extract_slice_chained_with_index() {
644 let val = json!({"m": [[1, 2, 3], [4, 5, 6]]});
645 let sel = Selector::parse("m[0][1:3]").unwrap();
646 let result = extract(&val, &sel).unwrap();
647 assert_eq!(result, vec![json!(2), json!(3)]);
648 }
649
650 #[test]
653 fn extract_keys_object() {
654 let val = json!({"b": 2, "a": 1});
655 let sel = Selector::parse("keys()").unwrap();
656 let result = extract(&val, &sel).unwrap();
657 let keys = &result[0];
659 assert!(keys.is_array());
660 let arr = keys.as_array().unwrap();
661 assert!(arr.contains(&json!("a")));
662 assert!(arr.contains(&json!("b")));
663 }
664
665 #[test]
666 fn extract_keys_array() {
667 let val = json!([10, 20, 30]);
668 let sel = Selector::parse("keys()").unwrap();
669 let result = extract(&val, &sel).unwrap();
670 assert_eq!(result, vec![json!([0, 1, 2])]);
671 }
672
673 #[test]
674 fn extract_values_object() {
675 let val = json!({"a": 1, "b": 2});
676 let sel = Selector::parse("values()").unwrap();
677 let result = extract(&val, &sel).unwrap();
678 let arr = result[0].as_array().unwrap();
679 assert!(arr.contains(&json!(1)));
680 assert!(arr.contains(&json!(2)));
681 }
682
683 #[test]
684 fn extract_length_array() {
685 let val = json!({"items": [1, 2, 3]});
686 let sel = Selector::parse("items.length()").unwrap();
687 let result = extract(&val, &sel).unwrap();
688 assert_eq!(result, vec![json!(3)]);
689 }
690
691 #[test]
692 fn extract_length_object() {
693 let val = json!({"a": 1, "b": 2, "c": 3});
694 let sel = Selector::parse("length()").unwrap();
695 let result = extract(&val, &sel).unwrap();
696 assert_eq!(result, vec![json!(3)]);
697 }
698
699 #[test]
700 fn extract_length_string() {
701 let val = json!({"name": "Alice"});
702 let sel = Selector::parse("name.length()").unwrap();
703 let result = extract(&val, &sel).unwrap();
704 assert_eq!(result, vec![json!(5)]);
705 }
706
707 #[test]
708 fn extract_length_null() {
709 let val = json!(null);
710 let sel = Selector::parse("length()").unwrap();
711 let result = extract(&val, &sel).unwrap();
712 assert_eq!(result, vec![json!(0)]);
713 }
714
715 #[test]
716 fn extract_keys_after_path() {
717 let val = json!({"data": {"x": 1, "y": 2}});
718 let sel = Selector::parse("data.keys()").unwrap();
719 let result = extract(&val, &sel).unwrap();
720 let arr = result[0].as_array().unwrap();
721 assert!(arr.contains(&json!("x")));
722 assert!(arr.contains(&json!("y")));
723 }
724
725 #[test]
726 fn extract_keys_on_string_error() {
727 let val = json!("hello");
728 let sel = Selector::parse("keys()").unwrap();
729 assert!(extract(&val, &sel).is_err());
730 }
731
732 #[test]
733 fn extract_length_on_number_error() {
734 let val = json!(42);
735 let sel = Selector::parse("length()").unwrap();
736 assert!(extract(&val, &sel).is_err());
737 }
738
739 #[test]
742 fn extract_recursive_simple() {
743 let val = json!({"a": {"b": {"name": "deep"}}});
744 let sel = Selector::parse("..name").unwrap();
745 let result = extract(&val, &sel).unwrap();
746 assert_eq!(result, vec![json!("deep")]);
747 }
748
749 #[test]
750 fn extract_recursive_multiple_matches() {
751 let val = json!({
752 "users": [
753 {"name": "Alice", "address": {"name": "Home"}},
754 {"name": "Bob"}
755 ]
756 });
757 let sel = Selector::parse("..name").unwrap();
758 let result = extract(&val, &sel).unwrap();
759 assert!(result.contains(&json!("Alice")));
760 assert!(result.contains(&json!("Home")));
761 assert!(result.contains(&json!("Bob")));
762 assert_eq!(result.len(), 3);
763 }
764
765 #[test]
766 fn extract_recursive_after_key() {
767 let val = json!({
768 "data": {
769 "nested": {"id": 1},
770 "deep": {"nested": {"id": 2}}
771 }
772 });
773 let sel = Selector::parse("data..id").unwrap();
774 let result = extract(&val, &sel).unwrap();
775 assert!(result.contains(&json!(1)));
776 assert!(result.contains(&json!(2)));
777 }
778
779 #[test]
780 fn extract_recursive_with_index() {
781 let val = json!({
782 "a": {"items": [10, 20]},
783 "b": {"items": [30, 40]}
784 });
785 let sel = Selector::parse("..items[0]").unwrap();
786 let result = extract(&val, &sel).unwrap();
787 assert!(result.contains(&json!(10)));
788 assert!(result.contains(&json!(30)));
789 }
790
791 #[test]
792 fn extract_recursive_not_found() {
793 let val = json!({"a": 1, "b": 2});
794 let sel = Selector::parse("..missing").unwrap();
795 assert!(extract(&val, &sel).is_err());
796 }
797
798 #[test]
799 fn extract_recursive_in_array() {
800 let val = json!([
801 {"id": 1, "children": [{"id": 2}]},
802 {"id": 3}
803 ]);
804 let sel = Selector::parse("..id").unwrap();
805 let result = extract(&val, &sel).unwrap();
806 assert_eq!(result, vec![json!(1), json!(2), json!(3)]);
807 }
808
809 #[test]
812 fn execute_single_selector() {
813 let val = json!({"name": "Alice", "age": 30});
814 let expr = Expression::parse("name").unwrap();
815 let result = execute(&val, &expr).unwrap();
816 assert_eq!(result, vec![json!("Alice")]);
817 }
818
819 #[test]
820 fn execute_multiple_selectors() {
821 let val = json!({"name": "Alice", "age": 30});
822 let expr = Expression::parse("name, age").unwrap();
823 let result = execute(&val, &expr).unwrap();
824 assert_eq!(result, vec![json!("Alice"), json!(30)]);
825 }
826
827 #[test]
828 fn execute_multi_selector_missing_one() {
829 let val = json!({"name": "Alice"});
830 let expr = Expression::parse("name, missing").unwrap();
831 let result = execute(&val, &expr).unwrap();
832 assert_eq!(result, vec![json!("Alice")]);
833 }
834
835 #[test]
836 fn execute_single_selector_missing_errors() {
837 let val = json!({"name": "Alice"});
838 let expr = Expression::parse("missing").unwrap();
839 assert!(execute(&val, &expr).is_err());
840 }
841
842 #[test]
845 fn execute_pipeline_simple_path() {
846 let val = json!({"items": [1, 2, 3]});
847 let expr = Expression::parse("items[0]").unwrap();
848 let result = execute(&val, &expr).unwrap();
849 assert_eq!(result, vec![json!(1)]);
850 }
851
852 #[test]
853 fn execute_pipeline_with_builtin() {
854 let val = json!({"data": {"x": 1, "y": 2}});
855 let expr = Expression::parse("data | keys()").unwrap();
856 let result = execute(&val, &expr).unwrap();
857 let arr = result[0].as_array().unwrap();
858 assert!(arr.contains(&json!("x")));
859 assert!(arr.contains(&json!("y")));
860 }
861
862 #[test]
863 fn execute_pipeline_with_length() {
864 let val = json!({"items": [1, 2, 3, 4, 5]});
865 let expr = Expression::parse("items | length()").unwrap();
866 let result = execute(&val, &expr).unwrap();
867 assert_eq!(result, vec![json!(5)]);
868 }
869
870 #[test]
871 fn execute_pipeline_select_filter() {
872 let val = json!({"items": [
873 {"name": "a", "price": 50},
874 {"name": "b", "price": 150},
875 {"name": "c", "price": 200}
876 ]});
877 let expr = Expression::parse("items[*] | select(.price > 100)").unwrap();
878 let result = execute(&val, &expr).unwrap();
879 assert_eq!(result.len(), 2);
880 assert_eq!(result[0]["name"], json!("b"));
881 assert_eq!(result[1]["name"], json!("c"));
882 }
883
884 #[test]
885 fn execute_pipeline_select_then_path() {
886 let val = json!({"items": [
887 {"name": "a", "price": 50},
888 {"name": "b", "price": 150}
889 ]});
890 let expr = Expression::parse("items[*] | select(.price > 100) | name").unwrap();
891 let result = execute(&val, &expr).unwrap();
892 assert_eq!(result, vec![json!("b")]);
893 }
894
895 #[test]
896 fn execute_pipeline_select_eq_string() {
897 let val = json!({"users": [
898 {"name": "Alice", "role": "admin"},
899 {"name": "Bob", "role": "user"}
900 ]});
901 let expr = Expression::parse("users[*] | select(.role == \"admin\")").unwrap();
902 let result = execute(&val, &expr).unwrap();
903 assert_eq!(result.len(), 1);
904 assert_eq!(result[0]["name"], json!("Alice"));
905 }
906
907 #[test]
908 fn execute_pipeline_select_regex() {
909 let val = json!({"items": [
910 {"name": "apple"},
911 {"name": "banana"},
912 {"name": "avocado"}
913 ]});
914 let expr = Expression::parse("items[*] | select(.name ~ \"^a\")").unwrap();
915 let result = execute(&val, &expr).unwrap();
916 assert_eq!(result.len(), 2);
917 }
918
919 #[test]
920 fn execute_pipeline_select_truthy() {
921 let val = json!({"items": [
922 {"name": "a", "active": true},
923 {"name": "b", "active": false},
924 {"name": "c", "active": true}
925 ]});
926 let expr = Expression::parse("items[*] | select(.active)").unwrap();
927 let result = execute(&val, &expr).unwrap();
928 assert_eq!(result.len(), 2);
929 }
930
931 #[test]
932 fn execute_pipeline_select_not_truthy() {
933 let val = json!({"items": [
934 {"name": "a", "active": true},
935 {"name": "b", "active": false}
936 ]});
937 let expr = Expression::parse("items[*] | select(not .active)").unwrap();
938 let result = execute(&val, &expr).unwrap();
939 assert_eq!(result.len(), 1);
940 assert_eq!(result[0]["name"], json!("b"));
941 }
942
943 #[test]
944 fn execute_pipeline_select_and() {
945 let val = json!({"items": [
946 {"price": 50, "stock": 10},
947 {"price": 150, "stock": 0},
948 {"price": 200, "stock": 5}
949 ]});
950 let expr = Expression::parse("items[*] | select(.price > 100 and .stock > 0)").unwrap();
951 let result = execute(&val, &expr).unwrap();
952 assert_eq!(result.len(), 1);
953 assert_eq!(result[0]["price"], json!(200));
954 }
955
956 #[test]
957 fn execute_pipeline_select_or() {
958 let val = json!({"items": [
959 {"price": 5, "featured": true},
960 {"price": 50, "featured": false},
961 {"price": 500, "featured": false}
962 ]});
963 let expr =
964 Expression::parse("items[*] | select(.price > 100 or .featured == true)").unwrap();
965 let result = execute(&val, &expr).unwrap();
966 assert_eq!(result.len(), 2);
967 }
968
969 #[test]
970 fn execute_pipeline_select_identity() {
971 let val = json!([1, 3, 5, 7, 9]);
973 let expr = Expression::parse("[*] | select(. > 5)").unwrap();
974 let result = execute(&val, &expr).unwrap();
975 assert_eq!(result, vec![json!(7), json!(9)]);
976 }
977
978 #[test]
979 fn execute_pipeline_select_lte() {
980 let val = json!([10, 20, 30, 40, 50]);
981 let expr = Expression::parse("[*] | select(. <= 30)").unwrap();
982 let result = execute(&val, &expr).unwrap();
983 assert_eq!(result, vec![json!(10), json!(20), json!(30)]);
984 }
985
986 #[test]
987 fn execute_pipeline_select_ne() {
988 let val = json!({"items": [
989 {"status": "active"},
990 {"status": "deleted"},
991 {"status": "active"}
992 ]});
993 let expr = Expression::parse("items[*] | select(.status != \"deleted\")").unwrap();
994 let result = execute(&val, &expr).unwrap();
995 assert_eq!(result.len(), 2);
996 }
997
998 #[test]
999 fn execute_pipeline_select_null_check() {
1000 let val = json!({"items": [
1001 {"name": "a", "email": null},
1002 {"name": "b", "email": "b@x.com"}
1003 ]});
1004 let expr = Expression::parse("items[*] | select(.email != null)").unwrap();
1005 let result = execute(&val, &expr).unwrap();
1006 assert_eq!(result.len(), 1);
1007 assert_eq!(result[0]["name"], json!("b"));
1008 }
1009
1010 #[test]
1013 fn execute_set_simple() {
1014 let val = json!({"name": "Alice", "age": 30});
1015 let expr = Expression::parse("set(.name, \"Bob\")").unwrap();
1016 let result = execute(&val, &expr).unwrap();
1017 assert_eq!(result[0]["name"], json!("Bob"));
1018 assert_eq!(result[0]["age"], json!(30));
1019 }
1020
1021 #[test]
1022 fn execute_set_nested() {
1023 let val = json!({"user": {"name": "Alice", "age": 30}});
1024 let expr = Expression::parse("set(.user.name, \"Bob\")").unwrap();
1025 let result = execute(&val, &expr).unwrap();
1026 assert_eq!(result[0]["user"]["name"], json!("Bob"));
1027 assert_eq!(result[0]["user"]["age"], json!(30));
1028 }
1029
1030 #[test]
1031 fn execute_set_number() {
1032 let val = json!({"count": 0});
1033 let expr = Expression::parse("set(.count, 42)").unwrap();
1034 let result = execute(&val, &expr).unwrap();
1035 assert_eq!(result[0]["count"], json!(42));
1036 }
1037
1038 #[test]
1039 fn execute_set_bool() {
1040 let val = json!({"active": false});
1041 let expr = Expression::parse("set(.active, true)").unwrap();
1042 let result = execute(&val, &expr).unwrap();
1043 assert_eq!(result[0]["active"], json!(true));
1044 }
1045
1046 #[test]
1047 fn execute_set_null() {
1048 let val = json!({"temp": "data"});
1049 let expr = Expression::parse("set(.temp, null)").unwrap();
1050 let result = execute(&val, &expr).unwrap();
1051 assert_eq!(result[0]["temp"], json!(null));
1052 }
1053
1054 #[test]
1055 fn execute_set_new_key() {
1056 let val = json!({"a": 1});
1057 let expr = Expression::parse("set(.b, 2)").unwrap();
1058 let result = execute(&val, &expr).unwrap();
1059 assert_eq!(result[0]["a"], json!(1));
1060 assert_eq!(result[0]["b"], json!(2));
1061 }
1062
1063 #[test]
1064 fn execute_set_array_index() {
1065 let val = json!({"items": [1, 2, 3]});
1066 let expr = Expression::parse("set(.items[1], 99)").unwrap();
1067 let result = execute(&val, &expr).unwrap();
1068 assert_eq!(result[0]["items"], json!([1, 99, 3]));
1069 }
1070
1071 #[test]
1072 fn execute_del_simple() {
1073 let val = json!({"name": "Alice", "temp": "data"});
1074 let expr = Expression::parse("del(.temp)").unwrap();
1075 let result = execute(&val, &expr).unwrap();
1076 assert_eq!(result[0], json!({"name": "Alice"}));
1077 }
1078
1079 #[test]
1080 fn execute_del_nested() {
1081 let val = json!({"user": {"name": "Alice", "temp": "x"}});
1082 let expr = Expression::parse("del(.user.temp)").unwrap();
1083 let result = execute(&val, &expr).unwrap();
1084 assert_eq!(result[0], json!({"user": {"name": "Alice"}}));
1085 }
1086
1087 #[test]
1088 fn execute_del_array_element() {
1089 let val = json!({"items": [1, 2, 3]});
1090 let expr = Expression::parse("del(.items[1])").unwrap();
1091 let result = execute(&val, &expr).unwrap();
1092 assert_eq!(result[0]["items"], json!([1, 3]));
1093 }
1094
1095 #[test]
1096 fn execute_del_missing_key() {
1097 let val = json!({"a": 1});
1099 let expr = Expression::parse("del(.missing)").unwrap();
1100 let result = execute(&val, &expr).unwrap();
1101 assert_eq!(result[0], json!({"a": 1}));
1102 }
1103
1104 #[test]
1105 fn execute_set_then_extract() {
1106 let val = json!({"name": "Alice"});
1107 let expr = Expression::parse("set(.name, \"Bob\") | name").unwrap();
1109 let result = execute(&val, &expr).unwrap();
1110 assert_eq!(result, vec![json!("Bob")]);
1111 }
1112
1113 #[test]
1114 fn execute_del_then_keys() {
1115 let val = json!({"a": 1, "b": 2, "c": 3});
1116 let expr = Expression::parse("del(.b) | keys()").unwrap();
1117 let result = execute(&val, &expr).unwrap();
1118 let arr = result[0].as_array().unwrap();
1119 assert!(arr.contains(&json!("a")));
1120 assert!(arr.contains(&json!("c")));
1121 assert!(!arr.contains(&json!("b")));
1122 }
1123
1124 #[test]
1127 fn slice_bound_none_returns_default() {
1128 assert_eq!(resolve_slice_bound(None, 0, 5), 0);
1129 assert_eq!(resolve_slice_bound(None, 5, 5), 5);
1130 }
1131
1132 #[test]
1133 fn slice_bound_positive() {
1134 assert_eq!(resolve_slice_bound(Some(2), 0, 5), 2);
1135 }
1136
1137 #[test]
1138 fn slice_bound_negative() {
1139 assert_eq!(resolve_slice_bound(Some(-2), 0, 5), 3);
1140 }
1141
1142 #[test]
1143 fn slice_bound_negative_past_zero() {
1144 assert_eq!(resolve_slice_bound(Some(-10), 0, 5), 0);
1145 }
1146
1147 #[test]
1150 fn builtin_keys_empty_object() {
1151 let result = apply_builtin(&Builtin::Keys, &json!({})).unwrap();
1152 assert_eq!(result, json!([]));
1153 }
1154
1155 #[test]
1156 fn builtin_values_empty_object() {
1157 let result = apply_builtin(&Builtin::Values, &json!({})).unwrap();
1158 assert_eq!(result, json!([]));
1159 }
1160
1161 #[test]
1162 fn builtin_length_empty_array() {
1163 let result = apply_builtin(&Builtin::Length, &json!([])).unwrap();
1164 assert_eq!(result, json!(0));
1165 }
1166
1167 #[test]
1168 fn builtin_length_empty_string() {
1169 let result = apply_builtin(&Builtin::Length, &json!("")).unwrap();
1170 assert_eq!(result, json!(0));
1171 }
1172
1173 #[test]
1174 fn builtin_values_array_passthrough() {
1175 let result = apply_builtin(&Builtin::Values, &json!([1, 2])).unwrap();
1176 assert_eq!(result, json!([1, 2]));
1177 }
1178
1179 #[test]
1186 fn extract_slice_deeply_nested() {
1187 let val = json!({"data": [{"items": [10, 20, 30, 40]}]});
1188 let sel = Selector::parse("data[0].items[1:3]").unwrap();
1189 let result = extract(&val, &sel).unwrap();
1190 assert_eq!(result, vec![json!(20), json!(30)]);
1191 }
1192
1193 #[test]
1194 fn extract_wildcard_then_slice() {
1195 let val = json!([[1, 2, 3], [4, 5, 6], [7, 8, 9]]);
1196 let sel = Selector::parse("[*][0:2]").unwrap();
1197 let result = extract(&val, &sel).unwrap();
1198 assert_eq!(
1199 result,
1200 vec![json!(1), json!(2), json!(4), json!(5), json!(7), json!(8)]
1201 );
1202 }
1203
1204 #[test]
1205 fn extract_slice_then_index() {
1206 let val = json!([[10, 20], [30, 40], [50, 60]]);
1207 let sel = Selector::parse("[0:2][0]").unwrap();
1208 let result = extract(&val, &sel).unwrap();
1209 assert_eq!(result, vec![json!(10), json!(30)]);
1210 }
1211
1212 #[test]
1213 fn extract_slice_zero_to_zero_empty() {
1214 let val = json!({"items": [1, 2, 3]});
1215 let sel = Selector::parse("items[0:0]").unwrap();
1216 let result = extract(&val, &sel).unwrap();
1217 assert!(result.is_empty());
1218 }
1219
1220 #[test]
1221 fn extract_slice_negative_out_of_bounds() {
1222 let val = json!({"items": [1, 2, 3]});
1224 let sel = Selector::parse("items[-100:]").unwrap();
1225 let result = extract(&val, &sel).unwrap();
1226 assert_eq!(result, vec![json!(1), json!(2), json!(3)]);
1227 }
1228
1229 #[test]
1230 fn extract_slice_negative_end_out_of_bounds() {
1231 let val = json!({"items": [1, 2, 3]});
1233 let sel = Selector::parse("items[:-100]").unwrap();
1234 let result = extract(&val, &sel).unwrap();
1235 assert!(result.is_empty());
1236 }
1237
1238 #[test]
1239 fn extract_slice_single_element() {
1240 let val = json!([10, 20, 30]);
1241 let sel = Selector::parse("[1:2]").unwrap();
1242 let result = extract(&val, &sel).unwrap();
1243 assert_eq!(result, vec![json!(20)]);
1244 }
1245
1246 #[test]
1247 fn extract_triple_index_depth() {
1248 let val = json!([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]);
1249 let sel = Selector::parse("[0][1][0]").unwrap();
1250 let result = extract(&val, &sel).unwrap();
1251 assert_eq!(result, vec![json!(3)]);
1252 }
1253
1254 #[test]
1255 fn extract_chained_wildcards() {
1256 let val = json!([[1, 2], [3, 4]]);
1257 let sel = Selector::parse("[*][*]").unwrap();
1258 let result = extract(&val, &sel).unwrap();
1259 assert_eq!(result, vec![json!(1), json!(2), json!(3), json!(4)]);
1260 }
1261
1262 #[test]
1265 fn extract_values_on_string_error() {
1266 let val = json!("hello");
1267 let sel = Selector::parse("values()").unwrap();
1268 assert!(extract(&val, &sel).is_err());
1269 }
1270
1271 #[test]
1272 fn extract_length_on_bool_error() {
1273 let val = json!(true);
1274 let sel = Selector::parse("length()").unwrap();
1275 assert!(extract(&val, &sel).is_err());
1276 }
1277
1278 #[test]
1279 fn extract_keys_on_null_error() {
1280 let val = json!(null);
1281 let sel = Selector::parse("keys()").unwrap();
1282 assert!(extract(&val, &sel).is_err());
1283 }
1284
1285 #[test]
1286 fn extract_builtin_on_wildcard_results() {
1287 let val = json!({"items": ["ab", "cde", "f"]});
1289 let sel = Selector::parse("items[*].length()").unwrap();
1290 let result = extract(&val, &sel).unwrap();
1291 assert_eq!(result, vec![json!(2), json!(3), json!(1)]);
1292 }
1293
1294 #[test]
1295 fn extract_keys_on_large_object() {
1296 let val = json!({"a": 1, "b": 2, "c": 3, "d": 4, "e": 5});
1297 let sel = Selector::parse("keys()").unwrap();
1298 let result = extract(&val, &sel).unwrap();
1299 assert_eq!(result[0].as_array().unwrap().len(), 5);
1300 }
1301
1302 #[test]
1305 fn extract_recursive_with_wildcard() {
1306 let val = json!({
1307 "a": {"items": [1, 2]},
1308 "b": {"items": [3, 4]}
1309 });
1310 let sel = Selector::parse("..items[*]").unwrap();
1311 let result = extract(&val, &sel).unwrap();
1312 assert!(result.contains(&json!(1)));
1313 assert!(result.contains(&json!(2)));
1314 assert!(result.contains(&json!(3)));
1315 assert!(result.contains(&json!(4)));
1316 }
1317
1318 #[test]
1319 fn extract_recursive_with_slice() {
1320 let val = json!({
1321 "a": {"items": [10, 20, 30]},
1322 "b": {"items": [40, 50, 60]}
1323 });
1324 let sel = Selector::parse("..items[0:2]").unwrap();
1325 let result = extract(&val, &sel).unwrap();
1326 assert!(result.contains(&json!(10)));
1327 assert!(result.contains(&json!(20)));
1328 assert!(result.contains(&json!(40)));
1329 assert!(result.contains(&json!(50)));
1330 }
1331
1332 #[test]
1333 fn extract_recursive_on_flat_value() {
1334 let val = json!({"name": "Alice"});
1336 let sel = Selector::parse("..name").unwrap();
1337 let result = extract(&val, &sel).unwrap();
1338 assert_eq!(result, vec![json!("Alice")]);
1339 }
1340
1341 #[test]
1342 fn extract_recursive_deeply_nested() {
1343 let val = json!({"a": {"b": {"c": {"d": {"target": 42}}}}});
1344 let sel = Selector::parse("..target").unwrap();
1345 let result = extract(&val, &sel).unwrap();
1346 assert_eq!(result, vec![json!(42)]);
1347 }
1348
1349 #[test]
1350 fn extract_recursive_in_mixed_arrays_and_objects() {
1351 let val = json!({
1352 "items": [
1353 {"id": 1, "sub": {"id": 10}},
1354 {"id": 2, "sub": [{"id": 20}, {"id": 21}]}
1355 ]
1356 });
1357 let sel = Selector::parse("..id").unwrap();
1358 let result = extract(&val, &sel).unwrap();
1359 assert!(result.contains(&json!(1)));
1360 assert!(result.contains(&json!(10)));
1361 assert!(result.contains(&json!(2)));
1362 assert!(result.contains(&json!(20)));
1363 assert!(result.contains(&json!(21)));
1364 assert_eq!(result.len(), 5);
1365 }
1366
1367 #[test]
1370 fn execute_multi_selector_both_missing() {
1371 let val = json!({"x": 1});
1372 let expr = Expression::parse("missing1, missing2").unwrap();
1373 let result = execute(&val, &expr).unwrap();
1374 assert!(result.is_empty());
1375 }
1376
1377 #[test]
1378 fn execute_multi_selector_with_array_paths() {
1379 let val = json!({"items": [1, 2, 3], "name": "test"});
1380 let expr = Expression::parse("items[0], name").unwrap();
1381 let result = execute(&val, &expr).unwrap();
1382 assert_eq!(result, vec![json!(1), json!("test")]);
1383 }
1384
1385 #[test]
1386 fn execute_multi_selector_with_nested() {
1387 let val = json!({"user": {"name": "Alice"}, "config": {"debug": true}});
1388 let expr = Expression::parse("user.name, config.debug").unwrap();
1389 let result = execute(&val, &expr).unwrap();
1390 assert_eq!(result, vec![json!("Alice"), json!(true)]);
1391 }
1392
1393 #[test]
1394 fn execute_multi_selector_same_key_twice() {
1395 let val = json!({"name": "Alice"});
1396 let expr = Expression::parse("name, name").unwrap();
1397 let result = execute(&val, &expr).unwrap();
1398 assert_eq!(result, vec![json!("Alice"), json!("Alice")]);
1399 }
1400
1401 #[test]
1404 fn execute_pipeline_three_stages() {
1405 let val = json!({"items": [
1406 {"name": "a", "price": 50},
1407 {"name": "b", "price": 150},
1408 {"name": "c", "price": 200}
1409 ]});
1410 let expr = Expression::parse("items[*] | select(.price > 100) | name").unwrap();
1411 let result = execute(&val, &expr).unwrap();
1412 assert_eq!(result, vec![json!("b"), json!("c")]);
1413 }
1414
1415 #[test]
1416 fn execute_pipeline_four_stages() {
1417 let val = json!({"items": [
1418 {"name": "ab", "active": true},
1419 {"name": "cde", "active": false},
1420 {"name": "fgh", "active": true}
1421 ]});
1422 let expr = Expression::parse("items[*] | select(.active) | name | length()").unwrap();
1423 let result = execute(&val, &expr).unwrap();
1424 assert_eq!(result, vec![json!(2), json!(3)]);
1425 }
1426
1427 #[test]
1428 fn execute_pipeline_builtin_chain() {
1429 let val = json!({"a": 1, "b": 2, "c": 3});
1431 let expr = Expression::parse("keys() | length()").unwrap();
1432 let result = execute(&val, &expr).unwrap();
1433 assert_eq!(result, vec![json!(3)]);
1434 }
1435
1436 #[test]
1437 fn execute_pipeline_values_then_length() {
1438 let val = json!({"a": 1, "b": 2});
1439 let expr = Expression::parse("values() | length()").unwrap();
1440 let result = execute(&val, &expr).unwrap();
1441 assert_eq!(result, vec![json!(2)]);
1442 }
1443
1444 #[test]
1445 fn execute_pipeline_path_builtin_select_path() {
1446 let val = json!({
1447 "data": {
1448 "users": [
1449 {"name": "Alice", "age": 25},
1450 {"name": "Bob", "age": 17}
1451 ]
1452 }
1453 });
1454 let expr = Expression::parse("data.users[*] | select(.age >= 18) | name").unwrap();
1455 let result = execute(&val, &expr).unwrap();
1456 assert_eq!(result, vec![json!("Alice")]);
1457 }
1458
1459 #[test]
1462 fn execute_pipeline_select_lt() {
1463 let val = json!([1, 5, 10, 15, 20]);
1464 let expr = Expression::parse("[*] | select(. < 10)").unwrap();
1465 let result = execute(&val, &expr).unwrap();
1466 assert_eq!(result, vec![json!(1), json!(5)]);
1467 }
1468
1469 #[test]
1470 fn execute_pipeline_select_gte() {
1471 let val = json!([1, 5, 10, 15, 20]);
1472 let expr = Expression::parse("[*] | select(. >= 10)").unwrap();
1473 let result = execute(&val, &expr).unwrap();
1474 assert_eq!(result, vec![json!(10), json!(15), json!(20)]);
1475 }
1476
1477 #[test]
1478 fn execute_pipeline_select_eq_bool() {
1479 let val = json!({"items": [
1480 {"name": "a", "done": true},
1481 {"name": "b", "done": false},
1482 {"name": "c", "done": true}
1483 ]});
1484 let expr = Expression::parse("items[*] | select(.done == true) | name").unwrap();
1485 let result = execute(&val, &expr).unwrap();
1486 assert_eq!(result, vec![json!("a"), json!("c")]);
1487 }
1488
1489 #[test]
1490 fn execute_pipeline_select_eq_null() {
1491 let val = json!({"items": [
1492 {"name": "a", "email": null},
1493 {"name": "b", "email": "b@x.com"},
1494 {"name": "c", "email": null}
1495 ]});
1496 let expr = Expression::parse("items[*] | select(.email == null) | name").unwrap();
1497 let result = execute(&val, &expr).unwrap();
1498 assert_eq!(result, vec![json!("a"), json!("c")]);
1499 }
1500
1501 #[test]
1502 fn execute_pipeline_select_all_filtered_out() {
1503 let val = json!([1, 2, 3]);
1504 let expr = Expression::parse("[*] | select(. > 100)").unwrap();
1505 let result = execute(&val, &expr).unwrap();
1506 assert!(result.is_empty());
1507 }
1508
1509 #[test]
1510 fn execute_pipeline_select_on_empty_array() {
1511 let val = json!({"items": []});
1512 let expr = Expression::parse("items[*] | select(. > 0)").unwrap();
1513 let result = execute(&val, &expr).unwrap();
1514 assert!(result.is_empty());
1515 }
1516
1517 #[test]
1518 fn execute_pipeline_select_complex_and_or() {
1519 let val = json!({"items": [
1520 {"a": 1, "b": 2, "c": 3},
1521 {"a": 1, "b": 2, "c": 0},
1522 {"a": 0, "b": 0, "c": 0}
1523 ]});
1524 let expr = Expression::parse("items[*] | select(.a == 1 or .b == 2 and .c == 3)").unwrap();
1526 let result = execute(&val, &expr).unwrap();
1527 assert_eq!(result.len(), 2);
1529 }
1530
1531 #[test]
1532 fn execute_pipeline_select_not_with_comparison() {
1533 let val = json!([
1534 {"status": "active"},
1535 {"status": "deleted"},
1536 {"status": "active"}
1537 ]);
1538 let expr = Expression::parse("[*] | select(not .status == \"deleted\")").unwrap();
1539 let result = execute(&val, &expr).unwrap();
1540 assert_eq!(result.len(), 2);
1541 }
1542
1543 #[test]
1544 fn execute_pipeline_select_string_comparison() {
1545 let val = json!(["apple", "banana", "cherry", "date"]);
1546 let expr = Expression::parse("[*] | select(. > \"c\")").unwrap();
1547 let result = execute(&val, &expr).unwrap();
1548 assert_eq!(result, vec![json!("cherry"), json!("date")]);
1549 }
1550
1551 #[test]
1552 fn execute_pipeline_select_regex_case_insensitive() {
1553 let val = json!(["Hello", "hello", "HELLO", "world"]);
1554 let expr = Expression::parse("[*] | select(. ~ \"(?i)^hello$\")").unwrap();
1555 let result = execute(&val, &expr).unwrap();
1556 assert_eq!(result, vec![json!("Hello"), json!("hello"), json!("HELLO")]);
1557 }
1558
1559 #[test]
1560 fn execute_pipeline_select_regex_digits() {
1561 let val = json!(["abc", "abc123", "456", "def"]);
1562 let expr = Expression::parse("[*] | select(. ~ \"\\\\d+\")").unwrap();
1563 let result = execute(&val, &expr).unwrap();
1564 assert_eq!(result, vec![json!("abc123"), json!("456")]);
1565 }
1566
1567 #[test]
1570 fn execute_set_then_del() {
1571 let val = json!({"a": 1, "b": 2});
1572 let expr = Expression::parse("set(.c, 3) | del(.a)").unwrap();
1573 let result = execute(&val, &expr).unwrap();
1574 assert_eq!(result[0]["b"], json!(2));
1575 assert_eq!(result[0]["c"], json!(3));
1576 assert!(result[0].get("a").is_none());
1577 }
1578
1579 #[test]
1580 fn execute_del_then_set() {
1581 let val = json!({"a": 1, "b": 2});
1582 let expr = Expression::parse("del(.b) | set(.c, 3)").unwrap();
1583 let result = execute(&val, &expr).unwrap();
1584 assert_eq!(result[0]["a"], json!(1));
1585 assert_eq!(result[0]["c"], json!(3));
1586 assert!(result[0].get("b").is_none());
1587 }
1588
1589 #[test]
1590 fn execute_multiple_set() {
1591 let val = json!({"x": 0, "y": 0});
1592 let expr = Expression::parse("set(.x, 1) | set(.y, 2)").unwrap();
1593 let result = execute(&val, &expr).unwrap();
1594 assert_eq!(result[0]["x"], json!(1));
1595 assert_eq!(result[0]["y"], json!(2));
1596 }
1597
1598 #[test]
1599 fn execute_multiple_del() {
1600 let val = json!({"a": 1, "b": 2, "c": 3});
1601 let expr = Expression::parse("del(.a) | del(.b)").unwrap();
1602 let result = execute(&val, &expr).unwrap();
1603 assert_eq!(result[0], json!({"c": 3}));
1604 }
1605
1606 #[test]
1607 fn execute_set_then_length() {
1608 let val = json!({"items": [1, 2]});
1609 let expr = Expression::parse("set(.name, \"test\") | keys() | length()").unwrap();
1610 let result = execute(&val, &expr).unwrap();
1611 assert_eq!(result, vec![json!(2)]);
1613 }
1614
1615 #[test]
1616 fn execute_del_array_then_length() {
1617 let val = json!({"items": [1, 2, 3]});
1618 let expr = Expression::parse("del(.items[0]) | items | length()").unwrap();
1619 let result = execute(&val, &expr).unwrap();
1620 assert_eq!(result, vec![json!(2)]);
1621 }
1622
1623 #[test]
1626 fn execute_pipeline_slice_then_select() {
1627 let val = json!({"items": [
1628 {"name": "a", "price": 10},
1629 {"name": "b", "price": 200},
1630 {"name": "c", "price": 50},
1631 {"name": "d", "price": 300}
1632 ]});
1633 let expr = Expression::parse("items[1:3] | select(.price > 100) | name").unwrap();
1634 let result = execute(&val, &expr).unwrap();
1635 assert_eq!(result, vec![json!("b")]);
1636 }
1637
1638 #[test]
1639 fn execute_pipeline_slice_then_builtin() {
1640 let val = json!({"items": [["a", "b"], ["c", "d", "e"]]});
1642 let expr = Expression::parse("items[0:2] | length()").unwrap();
1643 let result = execute(&val, &expr).unwrap();
1644 assert_eq!(result, vec![json!(2), json!(3)]);
1645 }
1646
1647 #[test]
1650 fn execute_cross_phase_slice_select_set() {
1651 let val = json!({"items": [
1652 {"name": "a", "active": true},
1653 {"name": "b", "active": false},
1654 {"name": "c", "active": true}
1655 ]});
1656 let expr =
1657 Expression::parse("items[0:2] | select(.active) | set(.selected, true)").unwrap();
1658 let result = execute(&val, &expr).unwrap();
1659 assert_eq!(result.len(), 1);
1660 assert_eq!(result[0]["name"], json!("a"));
1661 assert_eq!(result[0]["selected"], json!(true));
1662 }
1663
1664 #[test]
1667 fn value_type_names() {
1668 assert_eq!(value_type_name(&json!(null)), "null");
1669 assert_eq!(value_type_name(&json!(true)), "boolean");
1670 assert_eq!(value_type_name(&json!(42)), "number");
1671 assert_eq!(value_type_name(&json!("hi")), "string");
1672 assert_eq!(value_type_name(&json!([])), "array");
1673 assert_eq!(value_type_name(&json!({})), "object");
1674 }
1675
1676 #[test]
1679 fn extract_wildcard_nested_mixed_types() {
1680 let val = json!([{"name": "a"}, {"name": "b"}, {"name": "c"}]);
1681 let sel = Selector::parse("[*].name").unwrap();
1682 let result = extract(&val, &sel).unwrap();
1683 assert_eq!(result, vec![json!("a"), json!("b"), json!("c")]);
1684 }
1685
1686 #[test]
1687 fn extract_wildcard_single_element() {
1688 let val = json!([42]);
1689 let sel = Selector::parse("[*]").unwrap();
1690 let result = extract(&val, &sel).unwrap();
1691 assert_eq!(result, vec![json!(42)]);
1692 }
1693
1694 #[test]
1697 fn extract_negative_index_minus_2() {
1698 let val = json!([10, 20, 30, 40]);
1699 let sel = Selector::parse("[-2]").unwrap();
1700 let result = extract(&val, &sel).unwrap();
1701 assert_eq!(result, vec![json!(30)]);
1702 }
1703
1704 #[test]
1705 fn extract_negative_index_exactly_length() {
1706 let val = json!([10, 20, 30, 40]);
1708 let sel = Selector::parse("[-4]").unwrap();
1709 let result = extract(&val, &sel).unwrap();
1710 assert_eq!(result, vec![json!(10)]);
1711 }
1712
1713 #[test]
1716 fn extract_quoted_key_with_spaces() {
1717 let val = json!({"my key": "value"});
1718 let sel = Selector::parse("\"my key\"").unwrap();
1719 let result = extract(&val, &sel).unwrap();
1720 assert_eq!(result, vec![json!("value")]);
1721 }
1722
1723 #[test]
1724 fn extract_quoted_key_empty() {
1725 let val = json!({"": "empty key"});
1726 let sel = Selector::parse("\"\"").unwrap();
1727 let result = extract(&val, &sel).unwrap();
1728 assert_eq!(result, vec![json!("empty key")]);
1729 }
1730}