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