use regex::Regex;
use std::collections::HashMap;
lazy_static::lazy_static! {
static ref CLASS_PATTERNS: HashMap<&'static str, Vec<Regex>> = {
let mut map = HashMap::new();
map.insert("rs", vec![
Regex::new(r"struct\s+\w+").unwrap(),
Regex::new(r"enum\s+\w+").unwrap(),
Regex::new(r"trait\s+\w+").unwrap(),
]);
map.insert("py", vec![
Regex::new(r"class\s+\w+").unwrap(),
]);
map.insert("java", vec![
Regex::new(r"class\s+\w+").unwrap(),
Regex::new(r"interface\s+\w+").unwrap(),
]);
map.insert("kt", vec![
Regex::new(r"class\s+\w+").unwrap(),
Regex::new(r"interface\s+\w+").unwrap(),
]);
map.insert("js", vec![
Regex::new(r"class\s+\w+").unwrap(),
]);
map.insert("ts", vec![
Regex::new(r"class\s+\w+").unwrap(),
]);
map.insert("go", vec![
Regex::new(r"type\s+\w+\s+struct").unwrap(),
]);
map
};
static ref FUNCTION_PATTERNS: HashMap<&'static str, Vec<Regex>> = {
let mut map = HashMap::new();
map.insert("rs", vec![
Regex::new(r"fn\s+\w+").unwrap(),
]);
map.insert("py", vec![
Regex::new(r"def\s+\w+").unwrap(),
]);
map.insert("java", vec![
Regex::new(r"(?:public|private|protected)?\s*\w+\s+\w+\s*\(").unwrap(),
]);
map.insert("kt", vec![
Regex::new(r"(?:public|private|protected)?\s*\w+\s+\w+\s*\(").unwrap(),
]);
map.insert("js", vec![
Regex::new(r"function\s+\w+").unwrap(),
Regex::new(r"\w+\s*:\s*\([^)]*\)\s*=>").unwrap(),
]);
map.insert("ts", vec![
Regex::new(r"function\s+\w+").unwrap(),
Regex::new(r"\w+\s*:\s*\([^)]*\)\s*=>").unwrap(),
]);
map.insert("go", vec![
Regex::new(r"func\s+\w+").unwrap(),
]);
map
};
static ref FIELD_PATTERNS: HashMap<&'static str, Vec<Regex>> = {
let mut map = HashMap::new();
map.insert("rs", vec![
Regex::new(r"\w+:\s*\w+,").unwrap(),
]);
map.insert("py", vec![
Regex::new(r"self\.\w+\s*=").unwrap(),
]);
map.insert("java", vec![
Regex::new(r"(?:private|public|protected)\s+\w+\s+\w+;").unwrap(),
]);
map.insert("kt", vec![
Regex::new(r"(?:private|public|protected)\s+\w+\s+\w+;").unwrap(),
]);
map.insert("js", vec![
Regex::new(r"this\.\w+\s*=").unwrap(),
]);
map.insert("ts", vec![
Regex::new(r"this\.\w+\s*=").unwrap(),
]);
map
};
}
pub fn count_classes(content: &str, ext: &str) -> usize {
CLASS_PATTERNS
.get(ext)
.map(|patterns| patterns.iter().map(|re| re.find_iter(content).count()).sum())
.unwrap_or(0)
}
pub fn count_functions(content: &str, ext: &str) -> usize {
FUNCTION_PATTERNS
.get(ext)
.map(|patterns| patterns.iter().map(|re| re.find_iter(content).count()).sum())
.unwrap_or(0)
}
pub fn count_fields(content: &str, ext: &str) -> usize {
let count = FIELD_PATTERNS
.get(ext)
.map(|patterns| patterns.iter().map(|re| re.find_iter(content).count()).sum())
.unwrap_or(1);
count.max(1)
}
pub fn calculate_max_nesting(content: &str) -> usize {
let mut max_depth = 0;
let mut current_depth = 0;
for ch in content.chars() {
match ch {
'{' | '(' | '[' => {
current_depth += 1;
max_depth = max_depth.max(current_depth);
}
'}' | ')' | ']' => {
if current_depth > 0 {
current_depth -= 1;
}
}
_ => {}
}
}
max_depth
}