1use serde_json::Value;
2
3use crate::{
4 Error, OutputFormat, apply_pipeline_operation, format_output, parse_array_segment,
5 parse_query_segments, value_to_string,
6};
7
8pub fn execute_query(json: &Value, query: &str, format: OutputFormat) -> Result<(), Error> {
9 if query.contains('|') {
10 let parts: Vec<&str> = query.split('|').map(|s| s.trim()).collect();
13
14 if parts.len() < 2 {
15 return Err(Error::InvalidQuery("Invalid pipeline syntax".into()));
16 }
17
18 let initial_query = parts[0];
21 let mut current_data = execute_basic_query_as_json(json, initial_query)?;
22
23 for operation in &parts[1..] {
26 current_data = apply_pipeline_operation(current_data, &operation)?;
27 }
28
29 format_output(¤t_data, format)?;
32 } else {
33 let result_data = execute_basic_query_as_json(json, query)?;
34 format_output(&result_data, format)?;
35 }
36
37 Ok(())
38}
39
40pub fn execute_basic_query(json: &Value, query: &str) -> Result<Vec<String>, Error> {
41 let (segment, fields) = parse_query_segments(query)?;
42
43 if segment.contains('[') && segment.contains(']') {
44 let (idx, ridx) = parse_array_segment(segment)?; let key = segment
47 .get(..idx)
48 .ok_or(Error::InvalidQuery("Invalid segment format".into()))?;
49 let index_str = segment
50 .get(idx + 1..ridx)
51 .ok_or(Error::InvalidQuery("Invalid bracket content".into()))?;
52
53 if index_str.is_empty() {
54 let result = handle_array_access(json, key, fields)?;
55 Ok(result)
56 } else {
57 let index = index_str.parse::<usize>().map_err(|e| Error::StrToInt(e))?;
58 let result = handle_single_access(json, key, index, fields)?;
59 Ok(result)
60 }
61 } else {
62 let key = segment;
63 let result = handle_array_access(json, key, fields)?;
64 Ok(result)
65 }
66}
67
68pub fn execute_basic_query_as_json(json: &Value, query: &str) -> Result<Vec<Value>, Error> {
69 let (segment, fields) = parse_query_segments(query)?;
70
71 if segment.is_empty() && fields.is_empty() {
72 if let Value::Array(arr) = json {
73 return Ok(arr.clone());
74 } else {
75 return Ok(vec![json.clone()]);
76 }
77 }
78
79 if segment.is_empty() && !fields.is_empty() {
81 let first_field = fields[0];
82
83 if first_field.starts_with('[') && first_field.ends_with(']') {
84 let bracket_content = &first_field[1..first_field.len() - 1];
85
86 if bracket_content.is_empty() {
88 if let Value::Array(arr) = json {
89 if fields.len() > 1 {
90 let remaining_fields = fields[1..].to_vec();
91 let mut results = Vec::new();
92
93 for item in arr {
94 if let Ok(mut item_results) =
95 handle_nested_field_access(item, remaining_fields.clone())
96 {
97 results.append(&mut item_results);
98 }
99 }
100 return Ok(results);
101 } else {
102 return Ok(arr.clone());
103 }
104 } else {
105 return Err(Error::InvalidQuery(
106 "Cannot iterate over non-array value".into(),
107 ));
108 }
109 } else {
110 let index = bracket_content
112 .parse::<usize>()
113 .map_err(|e| Error::StrToInt(e))?;
114
115 if let Value::Array(arr) = json {
116 let item = arr.get(index).ok_or(Error::IndexOutOfBounds(index))?;
117
118 if fields.len() > 1 {
119 let remaining_fields = fields[1..].to_vec();
120 return handle_nested_field_access(item, remaining_fields);
121 } else {
122 return Ok(vec![item.clone()]);
123 }
124 } else {
125 return Err(Error::InvalidQuery("Cannot index non-array value".into()));
126 }
127 }
128 }
129 }
130
131 if segment.contains('[') && segment.contains(']') {
133 let (idx, ridx) = parse_array_segment(segment)?;
134 let key = segment
135 .get(..idx)
136 .ok_or(Error::InvalidQuery("Invalid segment format".into()))?;
137 let bracket_content = segment
138 .get(idx + 1..ridx)
139 .ok_or(Error::InvalidQuery("Invalid bracket content".into()))?;
140
141 if bracket_content.is_empty() {
142 let result = handle_array_access_as_json(json, key, fields)?;
143 Ok(result)
144 } else {
145 let index = bracket_content
146 .parse::<usize>()
147 .map_err(|e| Error::StrToInt(e))?;
148
149 let result = handle_single_access_as_json(json, key, index, fields)?;
151 if let Value::Array(arr) = result {
152 Ok(arr) } else {
154 Ok(vec![result]) }
156 }
157 } else {
158 let result = handle_array_access_as_json(json, segment, fields)?;
160 Ok(result)
161 }
162}
163
164pub fn handle_nested_field_access(json: &Value, fields: Vec<&str>) -> Result<Vec<Value>, Error> {
252 if fields.is_empty() {
257 return Ok(vec![json.clone()]);
258 }
259
260 let field = fields[0];
261 let remaining_fields = if fields.len() > 1 {
264 fields[1..].to_vec()
265 } else {
266 vec![]
267 };
268
269 if field.contains('[') && field.contains(']') {
273 let (idx, ridx) = parse_array_segment(field)?;
275 let key = &field[..idx];
276 let bracket_content = &field[idx + 1..ridx];
277
278 if let Some(array_or_object) = json.get(key) {
281 if bracket_content.is_empty() {
282 if let Value::Array(arr) = array_or_object {
284 if remaining_fields.is_empty() {
285 Ok(arr.clone())
287 } else {
288 let mut all_results = Vec::new();
290 for item in arr {
291 if let Ok(mut item_results) =
293 handle_nested_field_access(item, remaining_fields.clone())
294 {
295 all_results.append(&mut item_results);
297 }
298 }
299 Ok(all_results)
301 }
302 } else {
303 Err(Error::InvalidQuery(
304 format!("Cannot iterate over non-array field '{}'", key).into(),
305 ))
306 }
307 } else {
308 let index = bracket_content.parse::<usize>().map_err(|e| {
310 Error::InvalidQuery(
311 format!("Invalid array index '{}': {}", bracket_content, e).into(),
312 )
313 })?;
314
315 if let Value::Array(arr) = array_or_object {
316 if let Some(item) = arr.get(index) {
317 if remaining_fields.is_empty() {
318 Ok(vec![item.clone()])
319 } else {
320 handle_nested_field_access(item, remaining_fields)
321 }
322 } else {
323 Err(Error::IndexOutOfBounds(index))
324 }
325 } else {
326 Err(Error::InvalidQuery(
327 format!("Cannot index non-array field '{}'", key).into(),
328 ))
329 }
330 }
331 } else {
332 Err(Error::InvalidQuery(
333 format!("Field '{}' not found", key).into(),
334 ))
335 }
336 } else {
337 if let Some(value) = json.get(field) {
340 if remaining_fields.is_empty() {
342 Ok(vec![value.clone()])
343 } else {
344 handle_nested_field_access(value, remaining_fields)
346 }
347 } else {
348 Err(Error::InvalidQuery(
349 format!("Field '{}' not found", field).into(),
350 ))
351 }
352 }
353}
354
355pub fn handle_single_access_as_json(
410 json: &Value,
411 key: &str,
412 index: usize,
413 fields: Vec<&str>,
414) -> Result<Value, Error> {
415 let values = json
419 .get(key)
420 .ok_or(Error::InvalidQuery(format!("Key '{}' not found", key)))?;
421 let mut current = values.get(index).ok_or(Error::IndexOutOfBounds(index))?;
422
423 for (field_idx, field) in fields.iter().enumerate() {
424 if field.contains('[') && field.contains(']') {
427 let (idx, ridx) = parse_array_segment(field)?;
429 let field_key = field
430 .get(..idx)
431 .ok_or(Error::InvalidQuery("Invalid field".into()))?;
432 let index_str = field
433 .get(idx + 1..ridx)
434 .ok_or(Error::InvalidQuery("Invalid bracket content".into()))?;
435
436 let array = current.get(field_key).ok_or(Error::InvalidQuery(format!(
440 "Field '{}' not found",
441 field_key
442 )))?;
443
444 if index_str.is_empty() {
445 if let Value::Array(arr) = array {
447 let remaining_fields = if field_idx + 1 < fields.len() {
449 fields[field_idx + 1..].to_vec()
450 } else {
451 vec![]
452 };
453
454 if remaining_fields.is_empty() {
460 return Ok(Value::Array(arr.clone()));
462 } else {
463 let mut expanded_results = Vec::new();
465 for item in arr {
466 if let Ok(mut item_results) =
468 handle_nested_field_access(item, remaining_fields.clone())
469 {
470 expanded_results.append(&mut item_results);
471 }
472 }
473 return Ok(Value::Array(expanded_results));
474 }
475 } else {
476 return Err(Error::InvalidQuery(
477 format!("Field '{}' is not an array", field_key).into(),
478 ));
479 }
480 } else {
481 let field_index = index_str.parse::<usize>().map_err(|e| Error::StrToInt(e))?;
483 current = array
484 .get(field_index)
485 .ok_or(Error::IndexOutOfBounds(field_index))?;
486 }
487 } else {
488 println!("Normal field access: '{}'", field);
490 current = current
491 .get(field)
492 .ok_or(Error::InvalidQuery(format!("Field '{}' not found", field)))?;
493 }
494 }
495
496 Ok(current.clone())
497}
498
499pub fn handle_array_access_as_json(
500 json: &Value,
501 key: &str,
502 fields: Vec<&str>,
503) -> Result<Vec<Value>, Error> {
504 let values = json
505 .get(key)
506 .ok_or(Error::InvalidQuery(format!("Key '{}' not found", key)))?;
507 let values_arr = values
508 .as_array()
509 .ok_or(Error::InvalidQuery("Expected array".into()))?;
510
511 let res: Vec<Value> = values_arr
512 .iter()
513 .filter_map(|array_item| {
514 let mut current = array_item;
516
517 for field in &fields {
518 if field.contains('[') && field.contains(']') {
519 if let Ok((idx, ridx)) = parse_array_segment(field) {
521 if let Some(field_key) = field.get(..idx) {
522 if let Some(index_str) = field.get(idx + 1..ridx) {
523 if let Ok(field_index) = index_str.parse::<usize>() {
524 if let Some(array) = current.get(field_key) {
525 if let Some(item) = array.get(field_index) {
526 current = item;
527 continue;
528 }
529 }
530 }
531 }
532 }
533 }
534 return None;
536 } else {
537 if let Some(next) = current.get(field) {
539 current = next;
540 } else {
541 return None;
543 }
544 }
545 }
546
547 Some(current.clone())
549 })
550 .collect();
551
552 Ok(res)
553}
554
555pub fn handle_single_access(
556 json: &Value,
557 key: &str,
558 index: usize,
559 fields: Vec<&str>,
560) -> Result<Vec<String>, Error> {
561 let values = json
564 .get(key)
565 .ok_or(Error::InvalidQuery(format!("Key '{}' not found", key)))?;
566 let mut current = values.get(index).ok_or(Error::IndexOutOfBounds(index))?;
567
568 for field in fields {
571 if field.contains('[') && field.contains(']') {
572 let (idx, ridx) = parse_array_segment(field)?;
575 let field_key = field
576 .get(..idx)
577 .ok_or(Error::InvalidQuery("Invalid field".into()))?;
578 let index_str = field
579 .get(idx + 1..ridx)
580 .ok_or(Error::InvalidQuery("Invalid bracket content".into()))?;
581 let field_index = index_str.parse::<usize>().map_err(|e| Error::StrToInt(e))?;
582
583 let array = current.get(field_key).ok_or(Error::InvalidQuery(format!(
586 "Field '{}' not found",
587 field_key
588 )))?;
589 current = array
590 .get(field_index)
591 .ok_or(Error::IndexOutOfBounds(field_index))?;
592 } else {
593 current = current
595 .get(field)
596 .ok_or(Error::InvalidQuery(format!("Field '{}' not found", field)))?;
597 }
598 }
599
600 Ok(vec![value_to_string(current)])
601}
602
603pub fn handle_array_access(
604 json: &Value,
605 key: &str,
606 fields: Vec<&str>,
607) -> Result<Vec<String>, Error> {
608 let values = json
609 .get(key)
610 .ok_or(Error::InvalidQuery(format!("Key '{}' not found", key)))?;
611 let values_arr = values
612 .as_array()
613 .ok_or(Error::InvalidQuery("Expected array".into()))?;
614
615 let res: Vec<String> = values_arr
616 .iter()
617 .filter_map(|array_item| {
618 let mut current = array_item;
621
622 for field in &fields {
623 if field.contains('[') && field.contains(']') {
624 if let Ok((idx, ridx)) = parse_array_segment(field) {
627 if let Some(field_key) = field.get(..idx) {
628 if let Some(index_str) = field.get(idx + 1..ridx) {
629 if let Ok(field_index) = index_str.parse::<usize>() {
630 if let Some(array) = current.get(field_key) {
631 if let Some(item) = array.get(field_index) {
632 current = item;
633 continue;
634 }
635 }
636 }
637 }
638 }
639 }
640 return None;
643 } else {
644 if let Some(next) = current.get(field) {
647 current = next;
648 } else {
649 return None;
652 }
653 }
654 }
655
656 Some(value_to_string(current))
657 })
658 .collect();
659
660 Ok(res)
661}
662
663#[cfg(test)]
664mod tests {
665 use super::*;
666 use serde_json::{Value, json};
667
668 fn create_test_json() -> Value {
669 json!({
670 "users": [
671 {"name": "Alice", "age": 30, "active": true},
672 {"name": "Bob", "age": 25, "active": false},
673 {"name": "Carol", "age": 35}
674 ],
675 "products": [
676 {"title": "Laptop", "price": 1200},
677 {"title": "Mouse", "price": 25}
678 ],
679 "empty_array": [],
680 "not_array": "string_value"
681 })
682 }
683
684 #[test]
685 fn test_handle_array_access_normal_case() {
686 let json = create_test_json();
688 let result = handle_array_access(&json, "users", vec!["name"]);
689
690 assert!(result.is_ok());
691 let names = result.unwrap();
692 assert_eq!(names, vec!["Alice", "Bob", "Carol"]);
693 }
694
695 #[test]
696 fn test_handle_array_access_with_missing_field() {
697 let json = create_test_json();
699 let result = handle_array_access(&json, "users", vec!["active"]);
700
701 assert!(result.is_ok());
702 let actives = result.unwrap();
703 assert_eq!(actives, vec!["true", "false"]); }
705
706 #[test]
707 fn test_handle_array_access_different_types() {
708 let json = create_test_json();
710 let result = handle_array_access(&json, "users", vec!["age"]);
711
712 assert!(result.is_ok());
713 let ages = result.unwrap();
714 assert_eq!(ages, vec!["30", "25", "35"]);
715 }
716
717 #[test]
718 fn test_handle_array_access_empty_array() {
719 let json = create_test_json();
721 let result = handle_array_access(&json, "empty_array", vec!["name"]);
722
723 assert!(result.is_ok());
724 let names = result.unwrap();
725 assert!(names.is_empty());
726 }
727
728 #[test]
729 fn test_handle_array_access_key_not_found() {
730 let json = create_test_json();
732 let result = handle_array_access(&json, "nonexistent", vec!["name"]);
733
734 assert!(result.is_err());
735 match result.unwrap_err() {
736 Error::InvalidQuery(msg) => {
737 assert!(msg.contains("Key 'nonexistent' not found"));
738 }
739 _ => panic!("Expected InvalidQuery error"),
740 }
741 }
742
743 #[test]
744 fn test_handle_array_access_not_array() {
745 let json = create_test_json();
747 let result = handle_array_access(&json, "not_array", vec!["name"]);
748
749 assert!(result.is_err());
750 match result.unwrap_err() {
751 Error::InvalidQuery(msg) => {
752 assert!(msg.contains("Expected array"));
753 }
754 _ => panic!("Expected InvalidQuery error"),
755 }
756 }
757
758 #[test]
759 fn test_handle_array_access_field_not_in_any_element() {
760 let json = create_test_json();
762 let result = handle_array_access(&json, "users", vec!["nonexistent_field"]);
763
764 assert!(result.is_ok());
765 let values = result.unwrap();
766 assert!(values.is_empty()); }
768
769 #[test]
770 fn test_handle_single_access_normal_case() {
771 let json = create_test_json();
773 let result = handle_single_access(&json, "users", 0, vec!["name"]);
774
775 assert!(result.is_ok());
776 let names = result.unwrap();
777 assert_eq!(names, vec!["Alice"]);
778 }
779
780 #[test]
781 fn test_handle_single_access_different_index() {
782 let json = create_test_json();
784 let result = handle_single_access(&json, "users", 1, vec!["name"]);
785
786 assert!(result.is_ok());
787 let names = result.unwrap();
788 assert_eq!(names, vec!["Bob"]);
789 }
790
791 #[test]
792 fn test_handle_single_access_different_field() {
793 let json = create_test_json();
795 let result = handle_single_access(&json, "users", 0, vec!["age"]);
796
797 assert!(result.is_ok());
798 let ages = result.unwrap();
799 assert_eq!(ages, vec!["30"]);
800 }
801
802 #[test]
803 fn test_handle_single_access_boolean_field() {
804 let json = create_test_json();
806 let result = handle_single_access(&json, "users", 0, vec!["active"]);
807
808 assert!(result.is_ok());
809 let actives = result.unwrap();
810 assert_eq!(actives, vec!["true"]);
811 }
812
813 #[test]
814 fn test_handle_single_access_key_not_found() {
815 let json = create_test_json();
817 let result = handle_single_access(&json, "nonexistent", 0, vec!["name"]);
818
819 assert!(result.is_err());
820 match result.unwrap_err() {
821 Error::InvalidQuery(msg) => {
822 assert!(msg.contains("Key 'nonexistent' not found"));
823 }
824 _ => panic!("Expected InvalidQuery error"),
825 }
826 }
827
828 #[test]
829 fn test_handle_single_access_index_out_of_bounds() {
830 let json = create_test_json();
832 let result = handle_single_access(&json, "users", 999, vec!["name"]);
833
834 assert!(result.is_err());
835 match result.unwrap_err() {
836 Error::IndexOutOfBounds(index) => {
837 assert_eq!(index, 999);
838 }
839 _ => panic!("Expected IndexOutOfBounds error"),
840 }
841 }
842
843 #[test]
844 fn test_handle_single_access_field_not_found() {
845 let json = create_test_json();
847 let result = handle_single_access(&json, "users", 0, vec!["nonexistent_field"]);
848
849 assert!(result.is_err());
850 match result.unwrap_err() {
851 Error::InvalidQuery(msg) => {
852 assert!(msg.contains("Field 'nonexistent_field' not found"));
853 }
854 _ => panic!("Expected InvalidQuery error"),
855 }
856 }
857
858 #[test]
859 fn test_handle_single_access_not_array() {
860 let json = create_test_json();
862 let result = handle_single_access(&json, "not_array", 0, vec!["name"]);
863
864 assert!(result.is_err());
865 match result.unwrap_err() {
866 Error::IndexOutOfBounds(_) => {
867 }
869 _ => panic!("Expected IndexOutOfBounds error"),
870 }
871 }
872
873 #[test]
874 fn test_handle_single_access_empty_array() {
875 let json = create_test_json();
877 let result = handle_single_access(&json, "empty_array", 0, vec!["name"]);
878
879 assert!(result.is_err());
880 match result.unwrap_err() {
881 Error::IndexOutOfBounds(index) => {
882 assert_eq!(index, 0);
883 }
884 _ => panic!("Expected IndexOutOfBounds error"),
885 }
886 }
887
888 fn create_nested_test_json() -> Value {
889 json!({
890 "users": [
891 {
892 "name": "Alice",
893 "age": 30,
894 "address": {"city": "Tokyo", "country": "Japan"},
895 "projects": [
896 {"name": "Project A", "status": "active"},
897 {"name": "Project B", "status": "completed"}
898 ]
899 },
900 {
901 "name": "Bob",
902 "age": 25,
903 "address": {"city": "Osaka", "country": "Japan"},
904 "projects": [
905 {"name": "Project C", "status": "planning"}
906 ]
907 }
908 ]
909 })
910 }
911
912 #[test]
913 fn test_handle_single_access_simple() {
914 let json = create_nested_test_json();
915 let result = handle_single_access(&json, "users", 0, vec!["name"]);
916 assert!(result.is_ok());
917 assert_eq!(result.unwrap(), vec!["Alice"]);
918 }
919
920 #[test]
921 fn test_handle_single_access_nested_object() {
922 let json = create_nested_test_json();
923 let result = handle_single_access(&json, "users", 0, vec!["address", "city"]);
924 assert!(result.is_ok());
925 assert_eq!(result.unwrap(), vec!["Tokyo"]);
926 }
927
928 #[test]
929 fn test_handle_single_access_nested_array() {
930 let json = create_nested_test_json();
931 let result = handle_single_access(&json, "users", 0, vec!["projects[0]", "name"]);
932 assert!(result.is_ok());
933 assert_eq!(result.unwrap(), vec!["Project A"]);
934 }
935
936 #[test]
937 fn test_handle_single_access_deep_nesting() {
938 let json = create_nested_test_json();
939 let result = handle_single_access(&json, "users", 1, vec!["projects[0]", "status"]);
940 assert!(result.is_ok());
941 assert_eq!(result.unwrap(), vec!["planning"]);
942 }
943
944 #[test]
945 fn test_handle_single_access_nested_array_out_of_bounds() {
946 let json = create_nested_test_json();
947 let result = handle_single_access(&json, "users", 0, vec!["projects[999]", "name"]);
948 assert!(result.is_err());
949 }
950
951 #[test]
952 fn test_handle_array_access_simple() {
953 let json = create_nested_test_json();
954 let result = handle_array_access(&json, "users", vec!["name"]);
955 assert!(result.is_ok());
956 assert_eq!(result.unwrap(), vec!["Alice", "Bob"]);
957 }
958
959 #[test]
960 fn test_handle_array_access_nested_object() {
961 let json = create_nested_test_json();
962 let result = handle_array_access(&json, "users", vec!["address", "city"]);
963 assert!(result.is_ok());
964 assert_eq!(result.unwrap(), vec!["Tokyo", "Osaka"]);
965 }
966
967 #[test]
968 fn test_handle_array_access_nested_array() {
969 let json = create_nested_test_json();
970 let result = handle_array_access(&json, "users", vec!["projects[0]", "name"]);
971 assert!(result.is_ok());
972 assert_eq!(result.unwrap(), vec!["Project A", "Project C"]);
973 }
974
975 #[test]
976 fn test_handle_array_access_partial_data() {
977 let json = json!({
979 "items": [
980 {"details": {"name": "Item1"}},
981 {"other": "data"}, {"details": {"name": "Item3"}}
983 ]
984 });
985 let result = handle_array_access(&json, "items", vec!["details", "name"]);
986 assert!(result.is_ok());
987 assert_eq!(result.unwrap(), vec!["Item1", "Item3"]); }
989}