fn is_doc_comment(kind: &str, source: &str, sibling: Node) -> bool {
let is_comment = kind == "comment" || kind == "line_comment" || kind == "block_comment";
if !is_comment {
return false;
}
if kind == "line_comment" {
let comment_text = &source[sibling.byte_range()];
return comment_text.trim_start().starts_with("///");
}
true
}
fn find_doc_comment_start(node: Node, source: &str) -> usize {
let mut start_byte = node.start_byte();
let parent = match node.parent() {
Some(p) => p,
None => return start_byte,
};
let mut sibling_opt = node.prev_sibling();
while let Some(sibling) = sibling_opt {
if !is_doc_comment(sibling.kind(), source, sibling) {
let _ = parent; break;
}
start_byte = sibling.start_byte();
sibling_opt = sibling.prev_sibling();
}
start_byte
}
fn rust_node_to_chunk(kind: &str) -> Option<(ChunkType, &'static str, bool)> {
match kind {
"function_item" => Some((ChunkType::Function, "name", true)),
"impl_item" => Some((ChunkType::Class, "type", false)),
"mod_item" => Some((ChunkType::Module, "name", false)),
"struct_item" => Some((ChunkType::Struct, "name", true)),
"enum_item" => Some((ChunkType::Enum, "name", true)),
"trait_item" => Some((ChunkType::Trait, "name", true)),
"type_item" => Some((ChunkType::TypeAlias, "name", true)),
_ => None,
}
}
fn find_function_declarator_name<'a>(node: Node<'a>, _source: &str) -> Option<Node<'a>> {
if node.kind() == "identifier" {
return Some(node);
}
if node.kind() == "function_declarator" {
return find_function_declarator_name(node.child_by_field_name("declarator")?, _source);
}
if node.kind() == "pointer_declarator" {
return find_function_declarator_name(node.child_by_field_name("declarator")?, _source);
}
None
}
fn push_chunk(
chunks: &mut Vec<CodeChunk>,
chunk_type: ChunkType,
name: String,
language: &str,
node: Node,
content: String,
) {
let checksum = compute_checksum(&content);
chunks.push(CodeChunk {
file_path: String::new(),
chunk_type,
chunk_name: name,
language: language.to_string(),
start_line: node.start_position().row + 1,
end_line: node.end_position().row + 1,
content,
content_checksum: checksum,
});
}
fn compute_checksum(content: &str) -> String {
let mut hasher = Sha256::new();
hasher.update(content.as_bytes());
format!("{:x}", hasher.finalize())
}