hawk_data/
executor.rs

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        // 複数パイプライン処理
11        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        // 最初のクエリでデータを取得
18        let initial_query = parts[0].clone();
19        let mut current_data = execute_basic_query_as_json(json, &initial_query)?;
20
21        // 残りのパイプライン操作を順次実行
22        for operation in &parts[1..] {
23            current_data = apply_pipeline_operation(current_data, operation)?;
24        }
25
26        // 最終結果の出力
27        format_output(&current_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    // **新規追加: 単一オブジェクトへの直接フィールドアクセス**
76    // .Parameters のような単純なフィールドアクセスの場合
77    if !segment.is_empty() && fields.is_empty() && !segment.contains('[') {
78        if let Some(field_value) = json.get(segment) {
79            return Ok(vec![field_value.clone()]);
80        } else {
81            return Err(Error::InvalidQuery(format!(
82                "Field '{}' not found",
83                segment
84            )));
85        }
86    }
87
88    // ルート配列アクセス(.[0] のような場合)
89    if segment.is_empty() && !fields.is_empty() {
90        let first_field = fields[0];
91
92        if first_field.starts_with('[') && first_field.ends_with(']') {
93            let bracket_content = &first_field[1..first_field.len() - 1];
94
95            // 空括弧 [] の場合は配列全体を処理
96            if bracket_content.is_empty() {
97                if let Value::Array(arr) = json {
98                    if fields.len() > 1 {
99                        let remaining_fields = fields[1..].to_vec();
100                        let mut results = Vec::new();
101
102                        for item in arr {
103                            if let Ok(mut item_results) =
104                                handle_nested_field_access(item, remaining_fields.clone())
105                            {
106                                results.append(&mut item_results);
107                            }
108                        }
109                        return Ok(results);
110                    } else {
111                        return Ok(arr.clone());
112                    }
113                } else {
114                    return Err(Error::InvalidQuery(
115                        "Cannot iterate over non-array value".into(),
116                    ));
117                }
118            } else {
119                // 数値インデックスのみ
120                let index = bracket_content.parse::<usize>().map_err(Error::StrToInt)?;
121
122                if let Value::Array(arr) = json {
123                    let item = arr.get(index).ok_or(Error::IndexOutOfBounds(index))?;
124
125                    if fields.len() > 1 {
126                        let remaining_fields = fields[1..].to_vec();
127                        return handle_nested_field_access(item, remaining_fields);
128                    } else {
129                        return Ok(vec![item.clone()]);
130                    }
131                } else {
132                    return Err(Error::InvalidQuery("Cannot index non-array value".into()));
133                }
134            }
135        } else {
136            // **新規追加: 単一オブジェクトのネストしたフィールドアクセス**
137            // ルートが単一オブジェクトの場合のフィールドアクセス
138            return handle_nested_field_access(json, fields);
139        }
140    }
141
142    // 通常の配列アクセス(.users[0] のような場合)
143    if segment.contains('[') && segment.contains(']') {
144        let (idx, ridx) = parse_array_segment(segment)?;
145        let key = segment
146            .get(..idx)
147            .ok_or(Error::InvalidQuery("Invalid segment format".into()))?;
148        let bracket_content = segment
149            .get(idx + 1..ridx)
150            .ok_or(Error::InvalidQuery("Invalid bracket content".into()))?;
151
152        if bracket_content.is_empty() {
153            let result = handle_array_access_as_json(json, key, fields)?;
154            Ok(result)
155        } else {
156            let index = bracket_content.parse::<usize>().map_err(Error::StrToInt)?;
157
158            // 修正: 結果が配列の場合は展開
159            let result = handle_single_access_as_json(json, key, index, fields)?;
160            if let Value::Array(arr) = result {
161                Ok(arr) // 配列の場合は展開
162            } else {
163                Ok(vec![result]) // 単一値の場合はVecで包む
164            }
165        }
166    } else {
167        // **修正: 単一オブジェクトのフィールドアクセス対応**
168        // .Parameters.VpcCidr のようなネストしたアクセス
169        if !fields.is_empty() {
170            // segmentから開始してfieldsを辿る
171            if let Some(first_value) = json.get(segment) {
172                return handle_nested_field_access(first_value, fields);
173            } else {
174                return Err(Error::InvalidQuery(format!(
175                    "Field '{}' not found",
176                    segment
177                )));
178            }
179        } else {
180            // **修正: 単一オブジェクトの場合は配列として扱わない**
181            // 既存の handle_array_access_as_json は配列前提なので、単一オブジェクトでは使わない
182            if let Some(field_value) = json.get(segment) {
183                return Ok(vec![field_value.clone()]);
184            } else {
185                return Err(Error::InvalidQuery(format!(
186                    "Field '{}' not found",
187                    segment
188                )));
189            }
190        }
191    }
192}
193
194pub fn handle_nested_field_access(json: &Value, fields: Vec<&str>) -> Result<Vec<Value>, Error> {
195    if fields.is_empty() {
196        return Ok(vec![json.clone()]);
197    }
198
199    let field = fields[0];
200    let remaining_fields = if fields.len() > 1 {
201        fields[1..].to_vec()
202    } else {
203        vec![]
204    };
205
206    // 配列アクセス [0], [] の処理
207    if field.contains('[') && field.contains(']') {
208        let (idx, ridx) = parse_array_segment(field)?;
209        let key = &field[..idx];
210        let bracket_content = &field[idx + 1..ridx];
211
212        if let Some(array_or_object) = json.get(key) {
213            if bracket_content.is_empty() {
214                if let Value::Array(arr) = array_or_object {
215                    if remaining_fields.is_empty() {
216                        Ok(arr.clone())
217                    } else {
218                        let mut all_results = Vec::new();
219                        for item in arr {
220                            if let Ok(mut item_results) =
221                                handle_nested_field_access(item, remaining_fields.clone())
222                            {
223                                all_results.append(&mut item_results);
224                            }
225                        }
226                        Ok(all_results)
227                    }
228                } else {
229                    Err(Error::InvalidQuery(format!(
230                        "Cannot iterate over non-array field '{}'",
231                        key
232                    )))
233                }
234            } else {
235                // 数値インデックス [0] → 特定要素にアクセス
236                let index = bracket_content.parse::<usize>().map_err(|e| {
237                    Error::InvalidQuery(format!("Invalid array index '{}': {}", bracket_content, e))
238                })?;
239
240                if let Value::Array(arr) = array_or_object {
241                    if let Some(item) = arr.get(index) {
242                        if remaining_fields.is_empty() {
243                            Ok(vec![item.clone()])
244                        } else {
245                            handle_nested_field_access(item, remaining_fields)
246                        }
247                    } else {
248                        Err(Error::IndexOutOfBounds(index))
249                    }
250                } else {
251                    Err(Error::InvalidQuery(format!(
252                        "Cannot index non-array field '{}'",
253                        key
254                    )))
255                }
256            }
257        } else {
258            Err(Error::InvalidQuery(format!("Field '{}' not found", key)))
259        }
260    } else {
261        // 通常のフィールドアクセス
262        if let Some(value) = json.get(field) {
263            if remaining_fields.is_empty() {
264                Ok(vec![value.clone()])
265            } else {
266                handle_nested_field_access(value, remaining_fields)
267            }
268        } else {
269            Err(Error::InvalidQuery(format!("Field '{}' not found", field)))
270        }
271    }
272}
273
274pub fn handle_single_access_as_json(
275    json: &Value,
276    key: &str,
277    index: usize,
278    fields: Vec<&str>,
279) -> Result<Value, Error> {
280    let values = json
281        .get(key)
282        .ok_or(Error::InvalidQuery(format!("Key '{}' not found", key)))?;
283    let mut current = values.get(index).ok_or(Error::IndexOutOfBounds(index))?;
284
285    for (field_idx, field) in fields.iter().enumerate() {
286        if field.contains('[') && field.contains(']') {
287            let (idx, ridx) = parse_array_segment(field)?;
288            let field_key = field
289                .get(..idx)
290                .ok_or(Error::InvalidQuery("Invalid field".into()))?;
291            let index_str = field
292                .get(idx + 1..ridx)
293                .ok_or(Error::InvalidQuery("Invalid bracket content".into()))?;
294
295            // field_key でアクセス
296            let array = current.get(field_key).ok_or(Error::InvalidQuery(format!(
297                "Field '{}' not found",
298                field_key
299            )))?;
300
301            if index_str.is_empty() {
302                if let Value::Array(arr) = array {
303                    // 修正: 残りのフィールドがある場合の処理
304                    let remaining_fields = if field_idx + 1 < fields.len() {
305                        fields[field_idx + 1..].to_vec()
306                    } else {
307                        vec![]
308                    };
309
310                    if remaining_fields.is_empty() {
311                        // 残りフィールドなし → 配列全体を返す
312                        return Ok(Value::Array(arr.clone()));
313                    } else {
314                        // 修正: 残りフィールドあり → 各要素に適用
315                        let mut expanded_results = Vec::new();
316                        for item in arr {
317                            if let Ok(mut item_results) =
318                                handle_nested_field_access(item, remaining_fields.clone())
319                            {
320                                expanded_results.append(&mut item_results);
321                            }
322                        }
323                        return Ok(Value::Array(expanded_results));
324                    }
325                } else {
326                    return Err(Error::InvalidQuery(format!(
327                        "Field '{}' is not an array",
328                        field_key
329                    )));
330                }
331            } else {
332                // 数値インデックスの場合
333                let field_index = index_str.parse::<usize>().map_err(Error::StrToInt)?;
334                current = array
335                    .get(field_index)
336                    .ok_or(Error::IndexOutOfBounds(field_index))?;
337            }
338        } else {
339            // 通常のフィールドアクセス
340            current = current
341                .get(field)
342                .ok_or(Error::InvalidQuery(format!("Field '{}' not found", field)))?;
343        }
344    }
345
346    Ok(current.clone())
347}
348
349pub fn handle_array_access_as_json(
350    json: &Value,
351    key: &str,
352    fields: Vec<&str>,
353) -> Result<Vec<Value>, Error> {
354    let values = json
355        .get(key)
356        .ok_or(Error::InvalidQuery(format!("Key '{}' not found", key)))?;
357    let values_arr = values
358        .as_array()
359        .ok_or(Error::InvalidQuery("Expected array".into()))?;
360
361    let res: Vec<Value> = values_arr
362        .iter()
363        .filter_map(|array_item| {
364            // 各配列要素に対してフィールドパスを辿る
365            let mut current = array_item;
366
367            for field in &fields {
368                if field.contains('[') && field.contains(']') {
369                    // 配列アクセスの場合
370                    if let Ok((idx, ridx)) = parse_array_segment(field) {
371                        if let Some(field_key) = field.get(..idx) {
372                            if let Some(index_str) = field.get(idx + 1..ridx) {
373                                if let Ok(field_index) = index_str.parse::<usize>() {
374                                    if let Some(array) = current.get(field_key) {
375                                        if let Some(item) = array.get(field_index) {
376                                            current = item;
377                                            continue;
378                                        }
379                                    }
380                                }
381                            }
382                        }
383                    }
384                    // エラーの場合はこの要素をスキップ
385                    return None;
386                } else {
387                    // 通常のフィールドアクセス
388                    if let Some(next) = current.get(field) {
389                        current = next;
390                    } else {
391                        // フィールドが存在しない場合はこの要素をスキップ
392                        return None;
393                    }
394                }
395            }
396
397            Some(current.clone())
398        })
399        .collect();
400
401    Ok(res)
402}
403
404pub fn handle_single_access(
405    json: &Value,
406    key: &str,
407    index: usize,
408    fields: Vec<&str>,
409) -> Result<Vec<String>, Error> {
410    // 最初の配列要素を取得
411    let values = json
412        .get(key)
413        .ok_or(Error::InvalidQuery(format!("Key '{}' not found", key)))?;
414    let mut current = values.get(index).ok_or(Error::IndexOutOfBounds(index))?;
415
416    // fieldsを順次辿る
417    for field in fields {
418        if field.contains('[') && field.contains(']') {
419            // 配列アクセスの場合
420            let (idx, ridx) = parse_array_segment(field)?;
421            let field_key = field
422                .get(..idx)
423                .ok_or(Error::InvalidQuery("Invalid field".into()))?;
424            let index_str = field
425                .get(idx + 1..ridx)
426                .ok_or(Error::InvalidQuery("Invalid bracket content".into()))?;
427            let field_index = index_str.parse::<usize>().map_err(Error::StrToInt)?;
428
429            // field_key でアクセスしてから、field_index でアクセス
430            let array = current.get(field_key).ok_or(Error::InvalidQuery(format!(
431                "Field '{}' not found",
432                field_key
433            )))?;
434            current = array
435                .get(field_index)
436                .ok_or(Error::IndexOutOfBounds(field_index))?;
437        } else {
438            // Normal field access
439            current = current
440                .get(field)
441                .ok_or(Error::InvalidQuery(format!("Field '{}' not found", field)))?;
442        }
443    }
444
445    Ok(vec![value_to_string(current)])
446}
447
448pub fn handle_array_access(
449    json: &Value,
450    key: &str,
451    fields: Vec<&str>,
452) -> Result<Vec<String>, Error> {
453    let values = json
454        .get(key)
455        .ok_or(Error::InvalidQuery(format!("Key '{}' not found", key)))?;
456    let values_arr = values
457        .as_array()
458        .ok_or(Error::InvalidQuery("Expected array".into()))?;
459
460    let res: Vec<String> = values_arr
461        .iter()
462        .filter_map(|array_item| {
463            // 各配列要素に対してフィールドパスを辿る
464            let mut current = array_item;
465
466            for field in &fields {
467                if field.contains('[') && field.contains(']') {
468                    // 配列アクセスの場合
469                    if let Ok((idx, ridx)) = parse_array_segment(field) {
470                        if let Some(field_key) = field.get(..idx) {
471                            if let Some(index_str) = field.get(idx + 1..ridx) {
472                                if let Ok(field_index) = index_str.parse::<usize>() {
473                                    if let Some(array) = current.get(field_key) {
474                                        if let Some(item) = array.get(field_index) {
475                                            current = item;
476                                            continue;
477                                        }
478                                    }
479                                }
480                            }
481                        }
482                    }
483                    // エラーの場合はこの要素をスキップ
484                    return None;
485                } else {
486                    // 通常のフィールドアクセス
487                    if let Some(next) = current.get(field) {
488                        current = next;
489                    } else {
490                        // フィールドが存在しない場合はこの要素をスキップ
491                        return None;
492                    }
493                }
494            }
495
496            Some(value_to_string(current))
497        })
498        .collect();
499
500    Ok(res)
501}
502
503fn split_pipeline_respecting_parentheses(query: &str) -> Result<Vec<String>, Error> {
504    let mut parts = Vec::new();
505    let mut current_part = String::new();
506    let mut paren_depth = 0;
507    let chars = query.chars().peekable();
508
509    for ch in chars {
510        match ch {
511            '(' => {
512                paren_depth += 1;
513                current_part.push(ch);
514            }
515            ')' => {
516                paren_depth -= 1;
517                current_part.push(ch);
518            }
519            '|' if paren_depth == 0 => {
520                // 括弧の外のパイプのみで分割
521                if !current_part.trim().is_empty() {
522                    parts.push(current_part.trim().to_string());
523                    current_part.clear();
524                }
525            }
526            _ => {
527                current_part.push(ch);
528            }
529        }
530    }
531
532    // 最後の部分を追加
533    if !current_part.trim().is_empty() {
534        parts.push(current_part.trim().to_string());
535    }
536
537    if paren_depth != 0 {
538        return Err(Error::InvalidQuery(
539            "Unmatched parentheses in query".to_string(),
540        ));
541    }
542
543    Ok(parts)
544}
545
546#[cfg(test)]
547mod tests {
548    use super::*;
549    use serde_json::{json, Value};
550
551    #[test]
552    fn test_handle_single_access_simple() {
553        let json = create_nested_test_json();
554        let result = handle_single_access(&json, "users", 0, vec!["name"]);
555        assert!(result.is_ok());
556        assert_eq!(result.unwrap(), vec!["Alice"]);
557    }
558
559    #[test]
560    fn test_handle_single_access_nested_object() {
561        let json = create_nested_test_json();
562        let result = handle_single_access(&json, "users", 0, vec!["address", "city"]);
563        assert!(result.is_ok());
564        assert_eq!(result.unwrap(), vec!["Tokyo"]);
565    }
566
567    #[test]
568    fn test_handle_single_access_nested_array() {
569        let json = create_nested_test_json();
570        let result = handle_single_access(&json, "users", 0, vec!["projects[0]", "name"]);
571        assert!(result.is_ok());
572        assert_eq!(result.unwrap(), vec!["Project A"]);
573    }
574
575    #[test]
576    fn test_handle_single_access_deep_nesting() {
577        let json = create_nested_test_json();
578        let result = handle_single_access(&json, "users", 1, vec!["projects[0]", "status"]);
579        assert!(result.is_ok());
580        assert_eq!(result.unwrap(), vec!["planning"]);
581    }
582
583    #[test]
584    fn test_handle_single_access_nested_array_out_of_bounds() {
585        let json = create_nested_test_json();
586        let result = handle_single_access(&json, "users", 0, vec!["projects[999]", "name"]);
587        assert!(result.is_err());
588    }
589
590    #[test]
591    fn test_handle_array_access_simple() {
592        let json = create_nested_test_json();
593        let result = handle_array_access(&json, "users", vec!["name"]);
594        assert!(result.is_ok());
595        assert_eq!(result.unwrap(), vec!["Alice", "Bob"]);
596    }
597
598    #[test]
599    fn test_handle_array_access_nested_object() {
600        let json = create_nested_test_json();
601        let result = handle_array_access(&json, "users", vec!["address", "city"]);
602        assert!(result.is_ok());
603        assert_eq!(result.unwrap(), vec!["Tokyo", "Osaka"]);
604    }
605
606    #[test]
607    fn test_handle_array_access_nested_array() {
608        let json = create_nested_test_json();
609        let result = handle_array_access(&json, "users", vec!["projects[0]", "name"]);
610        assert!(result.is_ok());
611        assert_eq!(result.unwrap(), vec!["Project A", "Project C"]);
612    }
613
614    #[test]
615    fn test_handle_array_access_partial_data() {
616        // 一部の要素にフィールドがない場合
617        let json = json!({
618            "items": [
619                {"details": {"name": "Item1"}},
620                {"other": "data"},  // detailsフィールドなし
621                {"details": {"name": "Item3"}}
622            ]
623        });
624        let result = handle_array_access(&json, "items", vec!["details", "name"]);
625        assert!(result.is_ok());
626        assert_eq!(result.unwrap(), vec!["Item1", "Item3"]); // 中間要素はスキップ
627    }
628
629    // **新規追加: 単一オブジェクトアクセスのテスト**
630    #[test]
631    fn test_single_object_direct_field_access() {
632        let json = json!({
633            "Parameters": {
634                "VpcCidr": "10.0.0.0/16",
635                "SubnetCidr": "10.0.1.0/24"
636            },
637            "Resources": {
638                "VPC": {"Type": "AWS::EC2::VPC"}
639            }
640        });
641
642        // 直接フィールドアクセス
643        let result = execute_basic_query_as_json(&json, ".Parameters");
644        assert!(result.is_ok());
645        let values = result.unwrap();
646        assert_eq!(values.len(), 1);
647        assert!(values[0].is_object());
648        assert!(values[0].get("VpcCidr").is_some());
649    }
650
651    #[test]
652    fn test_single_object_nested_field_access() {
653        let json = json!({
654            "Parameters": {
655                "VpcCidr": "10.0.0.0/16",
656                "SubnetCidr": "10.0.1.0/24"
657            },
658            "Resources": {
659                "VPC": {"Type": "AWS::EC2::VPC"}
660            }
661        });
662
663        // ネストしたフィールドアクセス
664        let result = execute_basic_query_as_json(&json, ".Parameters.VpcCidr");
665        assert!(result.is_ok());
666        let values = result.unwrap();
667        assert_eq!(values.len(), 1);
668        assert_eq!(values[0], Value::String("10.0.0.0/16".to_string()));
669    }
670
671    #[test]
672    fn test_single_object_multiple_levels() {
673        let json = json!({
674            "Resources": {
675                "VPC": {
676                    "Type": "AWS::EC2::VPC",
677                    "Properties": {
678                        "CidrBlock": "10.0.0.0/16"
679                    }
680                }
681            }
682        });
683
684        let result = execute_basic_query_as_json(&json, ".Resources.VPC.Properties.CidrBlock");
685        assert!(result.is_ok());
686        let values = result.unwrap();
687        assert_eq!(values.len(), 1);
688        assert_eq!(values[0], Value::String("10.0.0.0/16".to_string()));
689    }
690
691    #[test]
692    fn test_single_object_field_not_found() {
693        let json = json!({
694            "Parameters": {
695                "VpcCidr": "10.0.0.0/16"
696            }
697        });
698
699        let result = execute_basic_query_as_json(&json, ".NonExistent");
700        assert!(result.is_err());
701        match result.unwrap_err() {
702            Error::InvalidQuery(msg) => {
703                assert!(msg.contains("Field 'NonExistent' not found"));
704            }
705            _ => panic!("Expected InvalidQuery error"),
706        }
707    }
708}
709
710pub fn test_handle_array_access_normal_case() {
711    // 正常ケース: 基本的な配列アクセス
712    let json = create_test_json();
713    let result = handle_array_access(&json, "users", vec!["name"]);
714
715    assert!(result.is_ok());
716    let names = result.unwrap();
717    assert_eq!(names, vec!["Alice", "Bob", "Carol"]);
718}
719
720#[test]
721fn test_handle_array_access_with_missing_field() {
722    // 正常ケース: 一部の要素にフィールドがない(filter_mapで対応)
723    let json = create_test_json();
724    let result = handle_array_access(&json, "users", vec!["active"]);
725
726    assert!(result.is_ok());
727    let actives = result.unwrap();
728    assert_eq!(actives, vec!["true", "false"]); // Carolにはactiveフィールドがない
729}
730
731#[test]
732fn test_handle_array_access_different_types() {
733    // 正常ケース: 異なる型のフィールド
734    let json = create_test_json();
735    let result = handle_array_access(&json, "users", vec!["age"]);
736
737    assert!(result.is_ok());
738    let ages = result.unwrap();
739    assert_eq!(ages, vec!["30", "25", "35"]);
740}
741
742#[test]
743fn test_handle_array_access_empty_array() {
744    // 正常ケース: 空の配列
745    let json = create_test_json();
746    let result = handle_array_access(&json, "empty_array", vec!["name"]);
747
748    assert!(result.is_ok());
749    let names = result.unwrap();
750    assert!(names.is_empty());
751}
752
753#[test]
754fn test_handle_array_access_key_not_found() {
755    // エラーケース: 存在しないキー
756    let json = create_test_json();
757    let result = handle_array_access(&json, "nonexistent", vec!["name"]);
758
759    assert!(result.is_err());
760    match result.unwrap_err() {
761        Error::InvalidQuery(msg) => {
762            assert!(msg.contains("Key 'nonexistent' not found"));
763        }
764        _ => panic!("Expected InvalidQuery error"),
765    }
766}
767
768#[test]
769fn test_handle_array_access_not_array() {
770    // エラーケース: 配列ではない値
771    let json = create_test_json();
772    let result = handle_array_access(&json, "not_array", vec!["name"]);
773
774    assert!(result.is_err());
775    match result.unwrap_err() {
776        Error::InvalidQuery(msg) => {
777            assert!(msg.contains("Expected array"));
778        }
779        _ => panic!("Expected InvalidQuery error"),
780    }
781}
782
783#[test]
784fn test_handle_array_access_field_not_in_any_element() {
785    // 正常ケース: どの要素にもフィールドがない
786    let json = create_test_json();
787    let result = handle_array_access(&json, "users", vec!["nonexistent_field"]);
788
789    assert!(result.is_ok());
790    let values = result.unwrap();
791    assert!(values.is_empty()); // filter_mapで空になる
792}
793
794#[test]
795fn test_handle_single_access_normal_case() {
796    // 正常ケース: 基本的な単一要素アクセス
797    let json = create_test_json();
798    let result = handle_single_access(&json, "users", 0, vec!["name"]);
799
800    assert!(result.is_ok());
801    let names = result.unwrap();
802    assert_eq!(names, vec!["Alice"]);
803}
804
805#[test]
806fn test_handle_single_access_different_index() {
807    // 正常ケース: 異なるインデックス
808    let json = create_test_json();
809    let result = handle_single_access(&json, "users", 1, vec!["name"]);
810
811    assert!(result.is_ok());
812    let names = result.unwrap();
813    assert_eq!(names, vec!["Bob"]);
814}
815
816#[test]
817fn test_handle_single_access_different_field() {
818    // 正常ケース: 異なるフィールド
819    let json = create_test_json();
820    let result = handle_single_access(&json, "users", 0, vec!["age"]);
821
822    assert!(result.is_ok());
823    let ages = result.unwrap();
824    assert_eq!(ages, vec!["30"]);
825}
826
827#[test]
828fn test_handle_single_access_boolean_field() {
829    // 正常ケース: Boolean型のフィールド
830    let json = create_test_json();
831    let result = handle_single_access(&json, "users", 0, vec!["active"]);
832
833    assert!(result.is_ok());
834    let actives = result.unwrap();
835    assert_eq!(actives, vec!["true"]);
836}
837
838#[test]
839fn test_handle_single_access_key_not_found() {
840    // エラーケース: 存在しないキー
841    let json = create_test_json();
842    let result = handle_single_access(&json, "nonexistent", 0, vec!["name"]);
843
844    assert!(result.is_err());
845    match result.unwrap_err() {
846        Error::InvalidQuery(msg) => {
847            assert!(msg.contains("Key 'nonexistent' not found"));
848        }
849        _ => panic!("Expected InvalidQuery error"),
850    }
851}
852
853#[test]
854fn test_handle_single_access_index_out_of_bounds() {
855    // エラーケース: 配列の範囲外インデックス
856    let json = create_test_json();
857    let result = handle_single_access(&json, "users", 999, vec!["name"]);
858
859    assert!(result.is_err());
860    match result.unwrap_err() {
861        Error::IndexOutOfBounds(index) => {
862            assert_eq!(index, 999);
863        }
864        _ => panic!("Expected IndexOutOfBounds error"),
865    }
866}
867
868#[test]
869fn test_handle_single_access_field_not_found() {
870    // エラーケース: 存在しないフィールド
871    let json = create_test_json();
872    let result = handle_single_access(&json, "users", 0, vec!["nonexistent_field"]);
873
874    assert!(result.is_err());
875    match result.unwrap_err() {
876        Error::InvalidQuery(msg) => {
877            assert!(msg.contains("Field 'nonexistent_field' not found"));
878        }
879        _ => panic!("Expected InvalidQuery error"),
880    }
881}
882
883#[test]
884fn test_handle_single_access_not_array() {
885    // エラーケース: 配列ではない値へのインデックスアクセス
886    let json = create_test_json();
887    let result = handle_single_access(&json, "not_array", 0, vec!["name"]);
888
889    assert!(result.is_err());
890    match result.unwrap_err() {
891        Error::IndexOutOfBounds(_) => {
892            // not_arrayは文字列なので、.get(0)がNoneを返してIndexOutOfBounds
893        }
894        _ => panic!("Expected IndexOutOfBounds error"),
895    }
896}
897
898#[test]
899fn test_handle_single_access_empty_array() {
900    // エラーケース: 空配列へのアクセス
901    let json = create_test_json();
902    let result = handle_single_access(&json, "empty_array", 0, vec!["name"]);
903
904    assert!(result.is_err());
905    match result.unwrap_err() {
906        Error::IndexOutOfBounds(index) => {
907            assert_eq!(index, 0);
908        }
909        _ => panic!("Expected IndexOutOfBounds error"),
910    }
911}
912
913pub fn create_nested_test_json() -> Value {
914    json!({
915        "users": [
916            {
917                "name": "Alice",
918                "age": 30,
919                "address": {"city": "Tokyo", "country": "Japan"},
920                "projects": [
921                    {"name": "Project A", "status": "active"},
922                    {"name": "Project B", "status": "completed"}
923                ]
924            },
925            {
926                "name": "Bob",
927                "age": 25,
928                "address": {"city": "Osaka", "country": "Japan"},
929                "projects": [
930                    {"name": "Project C", "status": "planning"}
931                ]
932            }
933        ]
934    })
935}
936
937pub fn create_test_json() -> Value {
938    json!({
939        "users": [
940            {"name": "Alice", "age": 30, "active": true},
941            {"name": "Bob", "age": 25, "active": false},
942            {"name": "Carol", "age": 35}
943        ],
944        "products": [
945            {"title": "Laptop", "price": 1200},
946            {"title": "Mouse", "price": 25}
947        ],
948        "empty_array": [],
949        "not_array": "string_value"
950    })
951}