use strsim::damerau_levenshtein;
use whippyunits_core::{Dimension, SiPrefix};
pub fn find_similar_scales(unknown_scale: &str, threshold: f64) -> Vec<(String, f64)> {
let mut suggestions = Vec::new();
let all_scales = get_all_available_scales();
for scale_name in all_scales {
let similarity = calculate_similarity(unknown_scale, &scale_name);
if similarity >= threshold {
suggestions.push((scale_name, similarity));
}
}
suggestions.sort_by(|a, b| b.1.partial_cmp(&a.1).unwrap_or(std::cmp::Ordering::Equal));
suggestions.truncate(3);
suggestions
}
fn calculate_similarity(s1: &str, s2: &str) -> f64 {
let distance = damerau_levenshtein(s1, s2);
let max_len = s1.len().max(s2.len()) as f64;
if max_len == 0.0 {
1.0
} else {
1.0 - (distance as f64 / max_len)
}
}
fn get_all_available_scales() -> Vec<String> {
let mut scales = Vec::new();
for dimension in Dimension::ALL {
for unit in dimension.units {
let capitalized_name = whippyunits_core::CapitalizedFmt(unit.name).to_string();
scales.push(capitalized_name);
}
}
for prefix in SiPrefix::ALL {
for dimension in Dimension::BASIS {
if let Some(base_unit) = dimension.units.first() {
let capitalized_name =
crate::utils::shared_utils::generate_scale_name(prefix.name(), base_unit.name);
scales.push(capitalized_name);
}
}
}
scales.sort();
scales.dedup();
scales
}