use crate::types::DeclarationFilter;
use regex::RegexSet;
use std::sync::LazyLock;
static DECLARATION_PATTERNS: LazyLock<RegexSet> = LazyLock::new(|| {
RegexSet::new([
r"^\s*pub\s+(fn|struct|enum|type|trait|use|mod|const|static|unsafe\s+fn)\b",
r"^\s*(fn|struct|enum|type|trait|impl|mod|const|static|unsafe\s+fn|macro)\b",
r"^\s*(let|mut)\s+",
r"^\s*(def|class)\s+",
r"^\s*(function|class|const|let|var|interface|type|enum)\s+",
r"^\s*(export|public|private|protected)\s+(function|class|const|let|var|interface|type)\b",
r"^\s*(func|struct|class|interface|typedef|enum|const|var|using)\s+",
r"^\s*(public|private|protected|static|final|abstract)\s+.*\b(class|interface|enum|void|int|float|double|bool|string|char|byte|long|short)\b",
r"^\s*(typedef|struct|union|enum)\b",
])
.expect("declaration patterns are valid")
});
pub fn is_declaration_line(line: &str) -> bool {
DECLARATION_PATTERNS.is_match(line)
}
pub fn should_include_declaration(line: &str, filter: Option<&DeclarationFilter>) -> bool {
match filter {
None => true,
Some(DeclarationFilter::Declarations) => is_declaration_line(line),
Some(DeclarationFilter::Usages) => !is_declaration_line(line),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_rust_function_declaration() {
assert!(is_declaration_line("fn main() {}"));
assert!(is_declaration_line("pub fn helper() {}"));
assert!(is_declaration_line(" pub fn indented() {}"));
}
#[test]
fn test_rust_struct_declaration() {
assert!(is_declaration_line("struct Point { x: i32, y: i32 }"));
assert!(is_declaration_line("pub struct Config;"));
}
#[test]
fn test_python_declaration() {
assert!(is_declaration_line("def helper():"));
assert!(is_declaration_line("class MyClass:"));
}
#[test]
fn test_js_declaration() {
assert!(is_declaration_line("function helper() {}"));
assert!(is_declaration_line("const x = 42;"));
assert!(is_declaration_line("class Helper {}"));
}
#[test]
fn test_usage_not_declaration() {
assert!(!is_declaration_line(" helper();"));
assert!(!is_declaration_line("println!(\"hello\");"));
assert!(!is_declaration_line("result = helper();"));
assert!(!is_declaration_line("do_something(helper);"));
}
#[test]
fn test_should_include_filter() {
assert!(should_include_declaration("fn main() {}", None));
assert!(should_include_declaration(
"fn main() {}",
Some(&DeclarationFilter::Declarations)
));
assert!(!should_include_declaration(
"helper();",
Some(&DeclarationFilter::Declarations)
));
assert!(should_include_declaration(
"helper();",
Some(&DeclarationFilter::Usages)
));
assert!(!should_include_declaration(
"fn main() {}",
Some(&DeclarationFilter::Usages)
));
}
}