Skip to main content

aptu_coder_core/languages/
yaml.rs

1// SPDX-FileCopyrightText: 2026 aptu-coder contributors
2// SPDX-License-Identifier: Apache-2.0
3//! YAML language handler for tree-sitter-yaml.
4//!
5//! Extracts top-level mapping keys as function-equivalent elements.
6//! YAML has no import concept; the import query is left empty.
7
8/// Tree-sitter query for extracting YAML block mapping keys as elements.
9///
10/// Each `block_mapping_pair` node's `key` field is captured as the element name.
11pub const ELEMENT_QUERY: &str = r"
12(block_mapping_pair key: (_) @func_name) @function
13";
14
15/// Tree-sitter call query for YAML (empty -- no call sites in YAML).
16pub const CALL_QUERY: &str = "";
17
18#[cfg(all(test, feature = "lang-yaml"))]
19mod tests {
20    use tree_sitter::{Parser, StreamingIterator};
21
22    fn parse_and_query(src: &str, query_str: &str, capture_name: &str) -> Vec<String> {
23        let language = tree_sitter_yaml::LANGUAGE;
24        let mut parser = Parser::new();
25        parser
26            .set_language(&language.into())
27            .expect("failed to set language");
28        let tree = parser.parse(src, None).expect("parse failed");
29        let query = tree_sitter::Query::new(&language.into(), query_str).expect("invalid query");
30        let mut cursor = tree_sitter::QueryCursor::new();
31        let mut matches = cursor.matches(&query, tree.root_node(), src.as_bytes());
32        let capture_idx = query
33            .capture_index_for_name(capture_name)
34            .expect("capture not found");
35        let mut results = Vec::new();
36        while let Some(m) = matches.next() {
37            for cap in m.captures {
38                if cap.index == capture_idx {
39                    let text = &src[cap.node.start_byte()..cap.node.end_byte()];
40                    results.push(text.trim().to_owned());
41                }
42            }
43        }
44        results
45    }
46
47    /// YAML block mapping keys are extracted as elements.
48    #[test]
49    fn test_yaml_block_mapping_element_extraction() {
50        let src = "name: my-project\nversion: 1.0.0\ndescription: A test project\n";
51        let names = parse_and_query(src, super::ELEMENT_QUERY, "func_name");
52        assert_eq!(names, vec!["name", "version", "description"]);
53    }
54
55    /// An empty YAML file returns empty analysis without errors.
56    #[test]
57    fn test_yaml_empty_file() {
58        let names = parse_and_query("", super::ELEMENT_QUERY, "func_name");
59        assert!(names.is_empty());
60    }
61
62    /// YAML multi-document stream extracts keys from each document.
63    #[test]
64    fn test_yaml_multi_document_stream() {
65        let src = "---\nfoo: bar\nbaz: qux\n---\nalpha: beta\n";
66        let names = parse_and_query(src, super::ELEMENT_QUERY, "func_name");
67        assert!(names.contains(&"foo".to_owned()));
68        assert!(names.contains(&"baz".to_owned()));
69        assert!(names.contains(&"alpha".to_owned()));
70    }
71}