1use serde_json::{json, Value};
2
3use crate::{
4 apply_pipeline_operation, format_output, parse_array_segment, parse_query_segments,
5 value_to_string, Error, OutputFormat,
6};
7
8pub fn execute_query(json: &Value, query: &str, format: OutputFormat) -> Result<(), Error> {
9 if query.contains('|') {
10 let parts = split_pipeline_respecting_parentheses(query)?;
12
13 if parts.len() < 2 {
14 return Err(Error::InvalidQuery("Invalid pipeline syntax".into()));
15 }
16
17 let initial_query = parts[0].clone();
19 let mut current_data = execute_basic_query_as_json(json, &initial_query)?;
20
21 for operation in &parts[1..] {
23 current_data = apply_pipeline_operation(current_data, operation)?;
24 }
25
26 format_output(¤t_data, format)?;
28 } else {
29 let result_data = execute_basic_query_as_json(json, query)?;
30 format_output(&result_data, format)?;
31 }
32
33 Ok(())
34}
35
36pub fn execute_basic_query(json: &Value, query: &str) -> Result<Vec<String>, Error> {
37 let (segment, fields) = parse_query_segments(query)?;
38
39 if segment.contains('[') && segment.contains(']') {
40 let (idx, ridx) = parse_array_segment(segment)?;
41
42 let key = segment
43 .get(..idx)
44 .ok_or(Error::InvalidQuery("Invalid segment format".into()))?;
45 let index_str = segment
46 .get(idx + 1..ridx)
47 .ok_or(Error::InvalidQuery("Invalid bracket content".into()))?;
48
49 if index_str.is_empty() {
50 let result = handle_array_access(json, key, fields)?;
51 Ok(result)
52 } else {
53 let index = index_str.parse::<usize>().map_err(Error::StrToInt)?;
54 let result = handle_single_access(json, key, index, fields)?;
55 Ok(result)
56 }
57 } else {
58 let key = segment;
59 let result = handle_array_access(json, key, fields)?;
60 Ok(result)
61 }
62}
63
64pub fn execute_basic_query_as_json(json: &Value, query: &str) -> Result<Vec<Value>, Error> {
65 let (segment, fields) = parse_query_segments(query)?;
66
67 if segment.is_empty() && fields.is_empty() {
68 if let Value::Array(arr) = json {
69 return Ok(arr.clone());
70 } else {
71 return Ok(vec![json.clone()]);
72 }
73 }
74
75 if !segment.is_empty() && fields.is_empty() && !segment.contains('[') {
77 if let Some(field_value) = json.get(segment) {
78 return Ok(vec![field_value.clone()]);
79 } else {
80 return Err(Error::InvalidQuery(format!("Field '{}' not found", segment)));
81 }
82 }
83
84 if segment.is_empty() && !fields.is_empty() {
86 let first_field = fields[0];
87
88 if first_field.starts_with('[') && first_field.ends_with(']') {
89 let bracket_content = &first_field[1..first_field.len() - 1];
90
91 if bracket_content.contains(':') {
93 if let Value::Array(arr) = json {
94 let (start, end) = parse_slice_notation(bracket_content)?;
95 let sliced = apply_array_slice(arr, start, end);
96
97 if fields.len() > 1 {
98 let remaining_fields = fields[1..].to_vec();
100 let mut results = Vec::new();
101
102 for item in sliced {
103 if let Ok(mut item_results) = handle_nested_field_access(&item, remaining_fields.clone()) {
104 results.append(&mut item_results);
105 }
106 }
107 return Ok(results);
108 } else {
109 return Ok(sliced);
110 }
111 } else {
112 return Err(Error::InvalidQuery("Cannot slice non-array value".into()));
113 }
114 }
115 else if bracket_content.is_empty() {
117 if let Value::Array(arr) = json {
118 if fields.len() > 1 {
119 let remaining_fields = fields[1..].to_vec();
120 let mut results = Vec::new();
121
122 for item in arr {
123 if let Ok(mut item_results) =
124 handle_nested_field_access(item, remaining_fields.clone())
125 {
126 results.append(&mut item_results);
127 }
128 }
129 return Ok(results);
130 } else {
131 return Ok(arr.clone());
132 }
133 } else {
134 return Err(Error::InvalidQuery(
135 "Cannot iterate over non-array value".into(),
136 ));
137 }
138 } else {
139 let index = bracket_content.parse::<usize>().map_err(Error::StrToInt)?;
141
142 if let Value::Array(arr) = json {
143 let item = arr.get(index).ok_or(Error::IndexOutOfBounds(index))?;
144
145 if fields.len() > 1 {
146 let remaining_fields = fields[1..].to_vec();
147 return handle_nested_field_access(item, remaining_fields);
148 } else {
149 return Ok(vec![item.clone()]);
150 }
151 } else {
152 return Err(Error::InvalidQuery("Cannot index non-array value".into()));
153 }
154 }
155 } else {
156 return handle_nested_field_access(json, fields);
158 }
159 }
160
161 if segment.contains('[') && segment.contains(']') {
163 let (idx, ridx) = parse_array_segment(segment)?;
164 let key = segment
165 .get(..idx)
166 .ok_or(Error::InvalidQuery("Invalid segment format".into()))?;
167 let bracket_content = segment
168 .get(idx + 1..ridx)
169 .ok_or(Error::InvalidQuery("Invalid bracket content".into()))?;
170
171 if bracket_content.contains(':') {
173 let field_value = json.get(key).ok_or(Error::InvalidQuery(format!("Key '{}' not found", key)))?;
174
175 if let Value::Array(arr) = field_value {
176 let (start, end) = parse_slice_notation(bracket_content)?;
177 let sliced = apply_array_slice(arr, start, end);
178
179 if !fields.is_empty() {
180 let mut results = Vec::new();
182 for item in sliced {
183 if let Ok(mut item_results) = handle_nested_field_access(&item, fields.clone()) {
184 results.append(&mut item_results);
185 }
186 }
187 Ok(results)
188 } else {
189 Ok(sliced)
190 }
191 } else {
192 Err(Error::InvalidQuery(format!("Field '{}' is not an array", key)))
193 }
194 }
195 else if bracket_content.is_empty() {
196 let result = handle_array_access_as_json(json, key, fields)?;
197 Ok(result)
198 } else {
199 let index = bracket_content.parse::<usize>().map_err(Error::StrToInt)?;
200
201 let result = handle_single_access_as_json(json, key, index, fields)?;
202 if let Value::Array(arr) = result {
203 Ok(arr)
204 } else {
205 Ok(vec![result])
206 }
207 }
208 } else {
209 if !fields.is_empty() {
211 if let Some(first_value) = json.get(segment) {
212 handle_nested_field_access(first_value, fields)
213 } else {
214 Err(Error::InvalidQuery(format!("Field '{}' not found", segment)))
215 }
216 } else if let Some(field_value) = json.get(segment) {
217 Ok(vec![field_value.clone()])
218 } else {
219 Err(Error::InvalidQuery(format!("Field '{}' not found", segment)))
220 }
221 }
222}
223
224pub fn handle_nested_field_access(json: &Value, fields: Vec<&str>) -> Result<Vec<Value>, Error> {
225 if fields.is_empty() {
226 return Ok(vec![json.clone()]);
227 }
228
229 let field = fields[0];
230 let remaining_fields = if fields.len() > 1 {
231 fields[1..].to_vec()
232 } else {
233 vec![]
234 };
235
236 if field.contains('[') && field.contains(']') {
238 let (idx, ridx) = parse_array_segment(field)?;
239 let key = &field[..idx];
240 let bracket_content = &field[idx + 1..ridx];
241
242 if let Some(array_or_object) = json.get(key) {
243 if bracket_content.is_empty() {
244 if let Value::Array(arr) = array_or_object {
245 if remaining_fields.is_empty() {
246 Ok(arr.clone())
247 } else {
248 let mut all_results = Vec::new();
249 for item in arr {
250 if let Ok(mut item_results) =
251 handle_nested_field_access(item, remaining_fields.clone())
252 {
253 all_results.append(&mut item_results);
254 }
255 }
256 Ok(all_results)
257 }
258 } else {
259 Err(Error::InvalidQuery(format!(
260 "Cannot iterate over non-array field '{}'",
261 key
262 )))
263 }
264 } else {
265 let index = bracket_content.parse::<usize>().map_err(|e| {
267 Error::InvalidQuery(format!("Invalid array index '{}': {}", bracket_content, e))
268 })?;
269
270 if let Value::Array(arr) = array_or_object {
271 if let Some(item) = arr.get(index) {
272 if remaining_fields.is_empty() {
273 Ok(vec![item.clone()])
274 } else {
275 handle_nested_field_access(item, remaining_fields)
276 }
277 } else {
278 Err(Error::IndexOutOfBounds(index))
279 }
280 } else {
281 Err(Error::InvalidQuery(format!(
282 "Cannot index non-array field '{}'",
283 key
284 )))
285 }
286 }
287 } else {
288 Err(Error::InvalidQuery(format!("Field '{}' not found", key)))
289 }
290 } else {
291 if let Some(value) = json.get(field) {
293 if remaining_fields.is_empty() {
294 Ok(vec![value.clone()])
295 } else {
296 handle_nested_field_access(value, remaining_fields)
297 }
298 } else {
299 Err(Error::InvalidQuery(format!("Field '{}' not found", field)))
300 }
301 }
302}
303
304pub fn handle_single_access_as_json(
305 json: &Value,
306 key: &str,
307 index: usize,
308 fields: Vec<&str>,
309) -> Result<Value, Error> {
310 let values = json
311 .get(key)
312 .ok_or(Error::InvalidQuery(format!("Key '{}' not found", key)))?;
313 let mut current = values.get(index).ok_or(Error::IndexOutOfBounds(index))?;
314
315 for (field_idx, field) in fields.iter().enumerate() {
316 if field.contains('[') && field.contains(']') {
317 let (idx, ridx) = parse_array_segment(field)?;
318 let field_key = field
319 .get(..idx)
320 .ok_or(Error::InvalidQuery("Invalid field".into()))?;
321 let index_str = field
322 .get(idx + 1..ridx)
323 .ok_or(Error::InvalidQuery("Invalid bracket content".into()))?;
324
325 let array = current.get(field_key).ok_or(Error::InvalidQuery(format!(
327 "Field '{}' not found",
328 field_key
329 )))?;
330
331 if index_str.is_empty() {
332 if let Value::Array(arr) = array {
333 let remaining_fields = if field_idx + 1 < fields.len() {
335 fields[field_idx + 1..].to_vec()
336 } else {
337 vec![]
338 };
339
340 if remaining_fields.is_empty() {
341 return Ok(Value::Array(arr.clone()));
343 } else {
344 let mut expanded_results = Vec::new();
346 for item in arr {
347 if let Ok(mut item_results) =
348 handle_nested_field_access(item, remaining_fields.clone())
349 {
350 expanded_results.append(&mut item_results);
351 }
352 }
353 return Ok(Value::Array(expanded_results));
354 }
355 } else {
356 return Err(Error::InvalidQuery(format!(
357 "Field '{}' is not an array",
358 field_key
359 )));
360 }
361 } else {
362 let field_index = index_str.parse::<usize>().map_err(Error::StrToInt)?;
364 current = array
365 .get(field_index)
366 .ok_or(Error::IndexOutOfBounds(field_index))?;
367 }
368 } else {
369 current = current
371 .get(field)
372 .ok_or(Error::InvalidQuery(format!("Field '{}' not found", field)))?;
373 }
374 }
375
376 Ok(current.clone())
377}
378
379pub fn handle_array_access_as_json(
380 json: &Value,
381 key: &str,
382 fields: Vec<&str>,
383) -> Result<Vec<Value>, Error> {
384 let values = json
385 .get(key)
386 .ok_or(Error::InvalidQuery(format!("Key '{}' not found", key)))?;
387 let values_arr = values
388 .as_array()
389 .ok_or(Error::InvalidQuery("Expected array".into()))?;
390
391 let res: Vec<Value> = values_arr
392 .iter()
393 .filter_map(|array_item| {
394 let mut current = array_item;
396
397 for field in &fields {
398 if field.contains('[') && field.contains(']') {
399 if let Ok((idx, ridx)) = parse_array_segment(field) {
401 if let Some(field_key) = field.get(..idx) {
402 if let Some(index_str) = field.get(idx + 1..ridx) {
403 if let Ok(field_index) = index_str.parse::<usize>() {
404 if let Some(array) = current.get(field_key) {
405 if let Some(item) = array.get(field_index) {
406 current = item;
407 continue;
408 }
409 }
410 }
411 }
412 }
413 }
414 return None;
416 } else {
417 if let Some(next) = current.get(field) {
419 current = next;
420 } else {
421 return None;
423 }
424 }
425 }
426
427 Some(current.clone())
428 })
429 .collect();
430
431 Ok(res)
432}
433
434pub fn handle_single_access(
435 json: &Value,
436 key: &str,
437 index: usize,
438 fields: Vec<&str>,
439) -> Result<Vec<String>, Error> {
440 let values = json
442 .get(key)
443 .ok_or(Error::InvalidQuery(format!("Key '{}' not found", key)))?;
444 let mut current = values.get(index).ok_or(Error::IndexOutOfBounds(index))?;
445
446 for field in fields {
448 if field.contains('[') && field.contains(']') {
449 let (idx, ridx) = parse_array_segment(field)?;
451 let field_key = field
452 .get(..idx)
453 .ok_or(Error::InvalidQuery("Invalid field".into()))?;
454 let index_str = field
455 .get(idx + 1..ridx)
456 .ok_or(Error::InvalidQuery("Invalid bracket content".into()))?;
457 let field_index = index_str.parse::<usize>().map_err(Error::StrToInt)?;
458
459 let array = current.get(field_key).ok_or(Error::InvalidQuery(format!(
461 "Field '{}' not found",
462 field_key
463 )))?;
464 current = array
465 .get(field_index)
466 .ok_or(Error::IndexOutOfBounds(field_index))?;
467 } else {
468 current = current
470 .get(field)
471 .ok_or(Error::InvalidQuery(format!("Field '{}' not found", field)))?;
472 }
473 }
474
475 Ok(vec![value_to_string(current)])
476}
477
478pub fn handle_array_access(
479 json: &Value,
480 key: &str,
481 fields: Vec<&str>,
482) -> Result<Vec<String>, Error> {
483 let values = json
484 .get(key)
485 .ok_or(Error::InvalidQuery(format!("Key '{}' not found", key)))?;
486 let values_arr = values
487 .as_array()
488 .ok_or(Error::InvalidQuery("Expected array".into()))?;
489
490 let res: Vec<String> = values_arr
491 .iter()
492 .filter_map(|array_item| {
493 let mut current = array_item;
495
496 for field in &fields {
497 if field.contains('[') && field.contains(']') {
498 if let Ok((idx, ridx)) = parse_array_segment(field) {
500 if let Some(field_key) = field.get(..idx) {
501 if let Some(index_str) = field.get(idx + 1..ridx) {
502 if let Ok(field_index) = index_str.parse::<usize>() {
503 if let Some(array) = current.get(field_key) {
504 if let Some(item) = array.get(field_index) {
505 current = item;
506 continue;
507 }
508 }
509 }
510 }
511 }
512 }
513 return None;
515 } else {
516 if let Some(next) = current.get(field) {
518 current = next;
519 } else {
520 return None;
522 }
523 }
524 }
525
526 Some(value_to_string(current))
527 })
528 .collect();
529
530 Ok(res)
531}
532
533fn split_pipeline_respecting_parentheses(query: &str) -> Result<Vec<String>, Error> {
534 let mut parts = Vec::new();
535 let mut current_part = String::new();
536 let mut paren_depth = 0;
537 let chars = query.chars().peekable();
538
539 for ch in chars {
540 match ch {
541 '(' => {
542 paren_depth += 1;
543 current_part.push(ch);
544 }
545 ')' => {
546 paren_depth -= 1;
547 current_part.push(ch);
548 }
549 '|' if paren_depth == 0 => {
550 if !current_part.trim().is_empty() {
552 parts.push(current_part.trim().to_string());
553 current_part.clear();
554 }
555 }
556 _ => {
557 current_part.push(ch);
558 }
559 }
560 }
561
562 if !current_part.trim().is_empty() {
564 parts.push(current_part.trim().to_string());
565 }
566
567 if paren_depth != 0 {
568 return Err(Error::InvalidQuery(
569 "Unmatched parentheses in query".to_string(),
570 ));
571 }
572
573 Ok(parts)
574}
575
576fn parse_slice_notation(bracket_content: &str) -> Result<(Option<usize>, Option<usize>), Error> {
578 if !bracket_content.contains(':') {
579 return Err(Error::InvalidQuery("Not a slice notation".to_string()));
580 }
581
582 let parts: Vec<&str> = bracket_content.split(':').collect();
583 if parts.len() != 2 {
584 return Err(Error::InvalidQuery("Invalid slice format, expected start:end".to_string()));
585 }
586
587 let start = if parts[0].is_empty() {
588 None } else {
590 Some(parts[0].parse::<usize>().map_err(|_| {
591 Error::InvalidQuery(format!("Invalid start index: {}", parts[0]))
592 })?)
593 };
594
595 let end = if parts[1].is_empty() {
596 None } else {
598 Some(parts[1].parse::<usize>().map_err(|_| {
599 Error::InvalidQuery(format!("Invalid end index: {}", parts[1]))
600 })?)
601 };
602
603 Ok((start, end))
604}
605
606fn apply_array_slice(array: &[Value], start: Option<usize>, end: Option<usize>) -> Vec<Value> {
608 let len = array.len();
609
610 let start_idx = start.unwrap_or(0);
611 let end_idx = end.unwrap_or(len);
612
613 let start_idx = start_idx.min(len);
615 let end_idx = end_idx.min(len);
616
617 if start_idx >= end_idx {
618 return Vec::new(); }
620
621 array[start_idx..end_idx].to_vec()
622}
623
624
625#[cfg(test)]
626mod tests {
627 use super::*;
628 use serde_json::{json, Value};
629
630 #[test]
631 fn test_handle_single_access_simple() {
632 let json = create_nested_test_json();
633 let result = handle_single_access(&json, "users", 0, vec!["name"]);
634 assert!(result.is_ok());
635 assert_eq!(result.unwrap(), vec!["Alice"]);
636 }
637
638 #[test]
639 fn test_handle_single_access_nested_object() {
640 let json = create_nested_test_json();
641 let result = handle_single_access(&json, "users", 0, vec!["address", "city"]);
642 assert!(result.is_ok());
643 assert_eq!(result.unwrap(), vec!["Tokyo"]);
644 }
645
646 #[test]
647 fn test_handle_single_access_nested_array() {
648 let json = create_nested_test_json();
649 let result = handle_single_access(&json, "users", 0, vec!["projects[0]", "name"]);
650 assert!(result.is_ok());
651 assert_eq!(result.unwrap(), vec!["Project A"]);
652 }
653
654 #[test]
655 fn test_handle_single_access_deep_nesting() {
656 let json = create_nested_test_json();
657 let result = handle_single_access(&json, "users", 1, vec!["projects[0]", "status"]);
658 assert!(result.is_ok());
659 assert_eq!(result.unwrap(), vec!["planning"]);
660 }
661
662 #[test]
663 fn test_handle_single_access_nested_array_out_of_bounds() {
664 let json = create_nested_test_json();
665 let result = handle_single_access(&json, "users", 0, vec!["projects[999]", "name"]);
666 assert!(result.is_err());
667 }
668
669 #[test]
670 fn test_handle_array_access_simple() {
671 let json = create_nested_test_json();
672 let result = handle_array_access(&json, "users", vec!["name"]);
673 assert!(result.is_ok());
674 assert_eq!(result.unwrap(), vec!["Alice", "Bob"]);
675 }
676
677 #[test]
678 fn test_handle_array_access_nested_object() {
679 let json = create_nested_test_json();
680 let result = handle_array_access(&json, "users", vec!["address", "city"]);
681 assert!(result.is_ok());
682 assert_eq!(result.unwrap(), vec!["Tokyo", "Osaka"]);
683 }
684
685 #[test]
686 fn test_handle_array_access_nested_array() {
687 let json = create_nested_test_json();
688 let result = handle_array_access(&json, "users", vec!["projects[0]", "name"]);
689 assert!(result.is_ok());
690 assert_eq!(result.unwrap(), vec!["Project A", "Project C"]);
691 }
692
693 #[test]
694 fn test_handle_array_access_partial_data() {
695 let json = json!({
697 "items": [
698 {"details": {"name": "Item1"}},
699 {"other": "data"}, {"details": {"name": "Item3"}}
701 ]
702 });
703 let result = handle_array_access(&json, "items", vec!["details", "name"]);
704 assert!(result.is_ok());
705 assert_eq!(result.unwrap(), vec!["Item1", "Item3"]); }
707
708 #[test]
710 fn test_single_object_direct_field_access() {
711 let json = json!({
712 "Parameters": {
713 "VpcCidr": "10.0.0.0/16",
714 "SubnetCidr": "10.0.1.0/24"
715 },
716 "Resources": {
717 "VPC": {"Type": "AWS::EC2::VPC"}
718 }
719 });
720
721 let result = execute_basic_query_as_json(&json, ".Parameters");
723 assert!(result.is_ok());
724 let values = result.unwrap();
725 assert_eq!(values.len(), 1);
726 assert!(values[0].is_object());
727 assert!(values[0].get("VpcCidr").is_some());
728 }
729
730 #[test]
731 fn test_single_object_nested_field_access() {
732 let json = json!({
733 "Parameters": {
734 "VpcCidr": "10.0.0.0/16",
735 "SubnetCidr": "10.0.1.0/24"
736 },
737 "Resources": {
738 "VPC": {"Type": "AWS::EC2::VPC"}
739 }
740 });
741
742 let result = execute_basic_query_as_json(&json, ".Parameters.VpcCidr");
744 assert!(result.is_ok());
745 let values = result.unwrap();
746 assert_eq!(values.len(), 1);
747 assert_eq!(values[0], Value::String("10.0.0.0/16".to_string()));
748 }
749
750 #[test]
751 fn test_single_object_multiple_levels() {
752 let json = json!({
753 "Resources": {
754 "VPC": {
755 "Type": "AWS::EC2::VPC",
756 "Properties": {
757 "CidrBlock": "10.0.0.0/16"
758 }
759 }
760 }
761 });
762
763 let result = execute_basic_query_as_json(&json, ".Resources.VPC.Properties.CidrBlock");
764 assert!(result.is_ok());
765 let values = result.unwrap();
766 assert_eq!(values.len(), 1);
767 assert_eq!(values[0], Value::String("10.0.0.0/16".to_string()));
768 }
769
770 #[test]
771 fn test_single_object_field_not_found() {
772 let json = json!({
773 "Parameters": {
774 "VpcCidr": "10.0.0.0/16"
775 }
776 });
777
778 let result = execute_basic_query_as_json(&json, ".NonExistent");
779 assert!(result.is_err());
780 match result.unwrap_err() {
781 Error::InvalidQuery(msg) => {
782 assert!(msg.contains("Field 'NonExistent' not found"));
783 }
784 _ => panic!("Expected InvalidQuery error"),
785 }
786 }
787}
788
789pub fn test_handle_array_access_normal_case() {
790 let json = create_test_json();
792 let result = handle_array_access(&json, "users", vec!["name"]);
793
794 assert!(result.is_ok());
795 let names = result.unwrap();
796 assert_eq!(names, vec!["Alice", "Bob", "Carol"]);
797}
798
799#[test]
800fn test_handle_array_access_with_missing_field() {
801 let json = create_test_json();
803 let result = handle_array_access(&json, "users", vec!["active"]);
804
805 assert!(result.is_ok());
806 let actives = result.unwrap();
807 assert_eq!(actives, vec!["true", "false"]); }
809
810#[test]
811fn test_handle_array_access_different_types() {
812 let json = create_test_json();
814 let result = handle_array_access(&json, "users", vec!["age"]);
815
816 assert!(result.is_ok());
817 let ages = result.unwrap();
818 assert_eq!(ages, vec!["30", "25", "35"]);
819}
820
821#[test]
822fn test_handle_array_access_empty_array() {
823 let json = create_test_json();
825 let result = handle_array_access(&json, "empty_array", vec!["name"]);
826
827 assert!(result.is_ok());
828 let names = result.unwrap();
829 assert!(names.is_empty());
830}
831
832#[test]
833fn test_handle_array_access_key_not_found() {
834 let json = create_test_json();
836 let result = handle_array_access(&json, "nonexistent", vec!["name"]);
837
838 assert!(result.is_err());
839 match result.unwrap_err() {
840 Error::InvalidQuery(msg) => {
841 assert!(msg.contains("Key 'nonexistent' not found"));
842 }
843 _ => panic!("Expected InvalidQuery error"),
844 }
845}
846
847#[test]
848fn test_handle_array_access_not_array() {
849 let json = create_test_json();
851 let result = handle_array_access(&json, "not_array", vec!["name"]);
852
853 assert!(result.is_err());
854 match result.unwrap_err() {
855 Error::InvalidQuery(msg) => {
856 assert!(msg.contains("Expected array"));
857 }
858 _ => panic!("Expected InvalidQuery error"),
859 }
860}
861
862#[test]
863fn test_handle_array_access_field_not_in_any_element() {
864 let json = create_test_json();
866 let result = handle_array_access(&json, "users", vec!["nonexistent_field"]);
867
868 assert!(result.is_ok());
869 let values = result.unwrap();
870 assert!(values.is_empty()); }
872
873#[test]
874fn test_handle_single_access_normal_case() {
875 let json = create_test_json();
877 let result = handle_single_access(&json, "users", 0, vec!["name"]);
878
879 assert!(result.is_ok());
880 let names = result.unwrap();
881 assert_eq!(names, vec!["Alice"]);
882}
883
884#[test]
885fn test_handle_single_access_different_index() {
886 let json = create_test_json();
888 let result = handle_single_access(&json, "users", 1, vec!["name"]);
889
890 assert!(result.is_ok());
891 let names = result.unwrap();
892 assert_eq!(names, vec!["Bob"]);
893}
894
895#[test]
896fn test_handle_single_access_different_field() {
897 let json = create_test_json();
899 let result = handle_single_access(&json, "users", 0, vec!["age"]);
900
901 assert!(result.is_ok());
902 let ages = result.unwrap();
903 assert_eq!(ages, vec!["30"]);
904}
905
906#[test]
907fn test_handle_single_access_boolean_field() {
908 let json = create_test_json();
910 let result = handle_single_access(&json, "users", 0, vec!["active"]);
911
912 assert!(result.is_ok());
913 let actives = result.unwrap();
914 assert_eq!(actives, vec!["true"]);
915}
916
917#[test]
918fn test_handle_single_access_key_not_found() {
919 let json = create_test_json();
921 let result = handle_single_access(&json, "nonexistent", 0, vec!["name"]);
922
923 assert!(result.is_err());
924 match result.unwrap_err() {
925 Error::InvalidQuery(msg) => {
926 assert!(msg.contains("Key 'nonexistent' not found"));
927 }
928 _ => panic!("Expected InvalidQuery error"),
929 }
930}
931
932#[test]
933fn test_handle_single_access_index_out_of_bounds() {
934 let json = create_test_json();
936 let result = handle_single_access(&json, "users", 999, vec!["name"]);
937
938 assert!(result.is_err());
939 match result.unwrap_err() {
940 Error::IndexOutOfBounds(index) => {
941 assert_eq!(index, 999);
942 }
943 _ => panic!("Expected IndexOutOfBounds error"),
944 }
945}
946
947#[test]
948fn test_handle_single_access_field_not_found() {
949 let json = create_test_json();
951 let result = handle_single_access(&json, "users", 0, vec!["nonexistent_field"]);
952
953 assert!(result.is_err());
954 match result.unwrap_err() {
955 Error::InvalidQuery(msg) => {
956 assert!(msg.contains("Field 'nonexistent_field' not found"));
957 }
958 _ => panic!("Expected InvalidQuery error"),
959 }
960}
961
962#[test]
963fn test_handle_single_access_not_array() {
964 let json = create_test_json();
966 let result = handle_single_access(&json, "not_array", 0, vec!["name"]);
967
968 assert!(result.is_err());
969 match result.unwrap_err() {
970 Error::IndexOutOfBounds(_) => {
971 }
973 _ => panic!("Expected IndexOutOfBounds error"),
974 }
975}
976
977#[test]
978fn test_handle_single_access_empty_array() {
979 let json = create_test_json();
981 let result = handle_single_access(&json, "empty_array", 0, vec!["name"]);
982
983 assert!(result.is_err());
984 match result.unwrap_err() {
985 Error::IndexOutOfBounds(index) => {
986 assert_eq!(index, 0);
987 }
988 _ => panic!("Expected IndexOutOfBounds error"),
989 }
990}
991
992pub fn create_nested_test_json() -> Value {
993 json!({
994 "users": [
995 {
996 "name": "Alice",
997 "age": 30,
998 "address": {"city": "Tokyo", "country": "Japan"},
999 "projects": [
1000 {"name": "Project A", "status": "active"},
1001 {"name": "Project B", "status": "completed"}
1002 ]
1003 },
1004 {
1005 "name": "Bob",
1006 "age": 25,
1007 "address": {"city": "Osaka", "country": "Japan"},
1008 "projects": [
1009 {"name": "Project C", "status": "planning"}
1010 ]
1011 }
1012 ]
1013 })
1014}
1015
1016pub fn create_test_json() -> Value {
1017 json!({
1018 "users": [
1019 {"name": "Alice", "age": 30, "active": true},
1020 {"name": "Bob", "age": 25, "active": false},
1021 {"name": "Carol", "age": 35}
1022 ],
1023 "products": [
1024 {"title": "Laptop", "price": 1200},
1025 {"title": "Mouse", "price": 25}
1026 ],
1027 "empty_array": [],
1028 "not_array": "string_value"
1029 })
1030}