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    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    // ルート配列アクセス(.[0] や .[0:5] のような場合)
85    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            // **新機能: スライス記法の処理**
92            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                        // スライス後にさらにフィールドアクセスがある場合
99                        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            // 空括弧 [] の場合は配列全体を処理
116            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                // 数値インデックスのみ
140                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            // 単一オブジェクトのネストしたフィールドアクセス
157            return handle_nested_field_access(json, fields);
158        }
159    }
160
161    // 通常の配列アクセス(.users[0:5] のような場合)
162    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        // **新機能: フィールド付きスライス記法の処理**
172        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                    // スライス後にフィールドアクセスがある場合
181                    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        // 単一オブジェクトのフィールドアクセス対応
210        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    // 配列アクセス [0], [] の処理
237    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                // 数値インデックス [0] → 特定要素にアクセス
266                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        // 通常のフィールドアクセス
292        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            // field_key でアクセス
326            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                    // 修正: 残りのフィールドがある場合の処理
334                    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                        // 残りフィールドなし → 配列全体を返す
342                        return Ok(Value::Array(arr.clone()));
343                    } else {
344                        // 修正: 残りフィールドあり → 各要素に適用
345                        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                // 数値インデックスの場合
363                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            // 通常のフィールドアクセス
370            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            // 各配列要素に対してフィールドパスを辿る
395            let mut current = array_item;
396
397            for field in &fields {
398                if field.contains('[') && field.contains(']') {
399                    // 配列アクセスの場合
400                    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                    // エラーの場合はこの要素をスキップ
415                    return None;
416                } else {
417                    // 通常のフィールドアクセス
418                    if let Some(next) = current.get(field) {
419                        current = next;
420                    } else {
421                        // フィールドが存在しない場合はこの要素をスキップ
422                        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    // 最初の配列要素を取得
441    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    // fieldsを順次辿る
447    for field in fields {
448        if field.contains('[') && field.contains(']') {
449            // 配列アクセスの場合
450            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            // field_key でアクセスしてから、field_index でアクセス
460            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            // Normal field access
469            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            // 各配列要素に対してフィールドパスを辿る
494            let mut current = array_item;
495
496            for field in &fields {
497                if field.contains('[') && field.contains(']') {
498                    // 配列アクセスの場合
499                    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                    // エラーの場合はこの要素をスキップ
514                    return None;
515                } else {
516                    // 通常のフィールドアクセス
517                    if let Some(next) = current.get(field) {
518                        current = next;
519                    } else {
520                        // フィールドが存在しない場合はこの要素をスキップ
521                        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                // 括弧の外のパイプのみで分割
551                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    // 最後の部分を追加
563    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
576/// 配列スライス記法をパース ([start:end] 形式)
577fn 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 // 空の場合は先頭から
589    } 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 // 空の場合は末尾まで
597    } 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
606/// 配列に対してスライス操作を適用
607fn 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    // 範囲チェック
614    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(); // 無効な範囲の場合は空を返す
619    }
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        // 一部の要素にフィールドがない場合
696        let json = json!({
697            "items": [
698                {"details": {"name": "Item1"}},
699                {"other": "data"},  // detailsフィールドなし
700                {"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"]); // 中間要素はスキップ
706    }
707
708    // **新規追加: 単一オブジェクトアクセスのテスト**
709    #[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        // 直接フィールドアクセス
722        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        // ネストしたフィールドアクセス
743        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    // 正常ケース: 基本的な配列アクセス
791    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    // 正常ケース: 一部の要素にフィールドがない(filter_mapで対応)
802    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"]); // Carolにはactiveフィールドがない
808}
809
810#[test]
811fn test_handle_array_access_different_types() {
812    // 正常ケース: 異なる型のフィールド
813    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    // 正常ケース: 空の配列
824    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    // エラーケース: 存在しないキー
835    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    // エラーケース: 配列ではない値
850    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    // 正常ケース: どの要素にもフィールドがない
865    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()); // filter_mapで空になる
871}
872
873#[test]
874fn test_handle_single_access_normal_case() {
875    // 正常ケース: 基本的な単一要素アクセス
876    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    // 正常ケース: 異なるインデックス
887    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    // 正常ケース: 異なるフィールド
898    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    // 正常ケース: Boolean型のフィールド
909    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    // エラーケース: 存在しないキー
920    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    // エラーケース: 配列の範囲外インデックス
935    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    // エラーケース: 存在しないフィールド
950    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    // エラーケース: 配列ではない値へのインデックスアクセス
965    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            // not_arrayは文字列なので、.get(0)がNoneを返してIndexOutOfBounds
972        }
973        _ => panic!("Expected IndexOutOfBounds error"),
974    }
975}
976
977#[test]
978fn test_handle_single_access_empty_array() {
979    // エラーケース: 空配列へのアクセス
980    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}