qex_core/chunk/languages/
rust_lang.rs1use super::{extract_preceding_comments, find_child_text, find_name, NodeMetadata, LanguageChunker};
2use crate::chunk::ChunkType;
3
4pub struct RustChunker;
5
6impl LanguageChunker for RustChunker {
7 fn tree_sitter_language(&self) -> tree_sitter::Language {
8 tree_sitter_rust::LANGUAGE.into()
9 }
10
11 fn language_name(&self) -> &str {
12 "rust"
13 }
14
15 fn file_extensions(&self) -> &[&str] {
16 &["rs"]
17 }
18
19 fn is_splittable(&self, node_type: &str) -> bool {
20 matches!(
21 node_type,
22 "function_item"
23 | "impl_item"
24 | "struct_item"
25 | "enum_item"
26 | "trait_item"
27 | "mod_item"
28 | "macro_definition"
29 )
30 }
31
32 fn has_nested_chunks(&self, node_type: &str) -> bool {
33 matches!(node_type, "impl_item" | "trait_item" | "mod_item")
34 }
35
36 fn classify_node(&self, node_type: &str, parent_name: Option<&str>) -> ChunkType {
37 match node_type {
38 "function_item" if parent_name.is_some() => ChunkType::Method,
39 "function_item" => ChunkType::Function,
40 "impl_item" => ChunkType::Impl,
41 "struct_item" => ChunkType::Struct,
42 "enum_item" => ChunkType::Enum,
43 "trait_item" => ChunkType::Trait,
44 "mod_item" => ChunkType::Module,
45 "macro_definition" => ChunkType::Macro,
46 _ => ChunkType::ModuleLevel,
47 }
48 }
49
50 fn extract_metadata(&self, node: tree_sitter::Node, source: &str) -> NodeMetadata {
51 let mut meta = NodeMetadata::default();
52
53 match node.kind() {
54 "function_item" => {
55 meta.name = find_name(node, source);
56 let text = &source[node.start_byte()..node.end_byte()];
57 meta.is_async = text.starts_with("async ") || text.starts_with("pub async ");
58 meta.docstring = extract_preceding_comments(node, source);
59 }
60 "impl_item" => {
61 meta.name = find_child_text(node, source, "type_identifier");
63 meta.docstring = extract_preceding_comments(node, source);
64 }
65 "struct_item" | "enum_item" => {
66 meta.name = find_child_text(node, source, "type_identifier");
67 meta.docstring = extract_preceding_comments(node, source);
68 }
69 "trait_item" => {
70 meta.name = find_child_text(node, source, "type_identifier");
71 meta.docstring = extract_preceding_comments(node, source);
72 }
73 "mod_item" => {
74 meta.name = find_name(node, source);
75 meta.docstring = extract_preceding_comments(node, source);
76 }
77 "macro_definition" => {
78 meta.name = find_name(node, source);
79 meta.docstring = extract_preceding_comments(node, source);
80 }
81 _ => {
82 meta.name = find_name(node, source);
83 meta.docstring = extract_preceding_comments(node, source);
84 }
85 }
86
87 if let Some(prev) = node.prev_sibling() {
89 if prev.kind() == "attribute_item" || prev.kind() == "inner_attribute_item" {
90 let text = &source[prev.start_byte()..prev.end_byte()];
91 meta.decorators.push(text.to_string());
92 }
93 }
94
95 meta
96 }
97}