use std::collections::HashSet;
pub fn compute_edge_weight(
ident: &str,
referencer: &str,
num_refs: usize,
mentioned_idents: &HashSet<String>,
chat_rel_fnames: &HashSet<String>,
num_definers: usize,
) -> f64 {
let mut mul = 1.0;
if mentioned_idents.contains(ident) {
mul *= 10.0;
}
if ident.len() >= 8 && is_meaningful_ident(ident) {
mul *= 10.0;
}
if ident.starts_with('_') {
mul *= 0.1;
}
if num_definers > 5 {
mul *= 0.1;
}
let use_mul = if chat_rel_fnames.contains(referencer) {
mul * 50.0
} else {
mul
};
use_mul * (num_refs as f64).sqrt()
}
pub fn is_meaningful_ident(s: &str) -> bool {
let has_alpha = s.chars().any(|c| c.is_alphabetic());
if !has_alpha {
return false;
}
if s.contains('_') {
return true;
}
if s.contains('-') {
return true;
}
let has_upper = s.chars().any(|c| c.is_uppercase());
let has_lower = s.chars().any(|c| c.is_lowercase());
if has_upper && has_lower {
return true;
}
false
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn is_meaningful_snake_case() {
assert!(is_meaningful_ident("my_function"));
assert!(is_meaningful_ident("CONST_VALUE"));
}
#[test]
fn is_meaningful_kebab_case() {
assert!(is_meaningful_ident("my-component"));
}
#[test]
fn is_meaningful_camel_case() {
assert!(is_meaningful_ident("myFunction"));
assert!(is_meaningful_ident("MyClass"));
}
#[test]
fn is_meaningful_short_or_simple() {
assert!(!is_meaningful_ident("foo")); assert!(!is_meaningful_ident("FOO")); assert!(!is_meaningful_ident("123")); }
#[test]
fn weight_basic() {
let mentioned = HashSet::new();
let chat_files = HashSet::new();
let weight = compute_edge_weight("foo", "file.rs", 1, &mentioned, &chat_files, 1);
assert!((weight - 1.0).abs() < 0.001);
}
#[test]
fn weight_mentioned_ident() {
let mut mentioned = HashSet::new();
mentioned.insert("my_function".to_string());
let chat_files = HashSet::new();
let weight = compute_edge_weight("my_function", "file.rs", 1, &mentioned, &chat_files, 1);
assert!((weight - 100.0).abs() < 0.001);
}
#[test]
fn weight_chat_file() {
let mentioned = HashSet::new();
let mut chat_files = HashSet::new();
chat_files.insert("main.rs".to_string());
let weight = compute_edge_weight("foo", "main.rs", 4, &mentioned, &chat_files, 1);
assert!((weight - 100.0).abs() < 0.001);
}
#[test]
fn weight_underscore_prefix() {
let mentioned = HashSet::new();
let chat_files = HashSet::new();
let weight = compute_edge_weight("_private", "file.rs", 1, &mentioned, &chat_files, 1);
assert!((weight - 1.0).abs() < 0.001);
}
#[test]
fn weight_many_definers() {
let mentioned = HashSet::new();
let chat_files = HashSet::new();
let weight = compute_edge_weight("foo", "file.rs", 1, &mentioned, &chat_files, 10);
assert!((weight - 0.1).abs() < 0.001);
}
#[test]
fn weight_multiple_refs() {
let mentioned = HashSet::new();
let chat_files = HashSet::new();
let weight = compute_edge_weight("foo", "file.rs", 9, &mentioned, &chat_files, 1);
assert!((weight - 3.0).abs() < 0.001);
}
}