use alloc::string::String;
use alloc::vec::Vec;
const FILE_EXTENSIONS: [&str; 8] = ["dart", "rb", "py", "js", "jsx", "ts", "tsx", "php"];
fn is_file_path(expression: &str) -> bool {
expression.contains('/') || expression.matches('.').count() == 1
}
fn file_extension(name: &str) -> Option<&str> {
let base_name = name
.rsplit_once('/')
.map_or(name, |(_, base_name)| base_name);
let (stem, extension) = base_name.rsplit_once('.')?;
stem.contains(|c| c != '.').then_some(extension)
}
fn strip_file_extension(name: &str) -> &str {
if !is_file_path(name) {
return name;
}
file_extension(name)
.filter(|extension| {
FILE_EXTENSIONS
.iter()
.any(|known| extension.eq_ignore_ascii_case(known))
})
.and_then(|extension| name.strip_suffix(extension)?.strip_suffix('.'))
.unwrap_or(name)
}
#[must_use]
pub fn normalize_module_path(expression: &str) -> String {
let segments: Vec<&str> = strip_file_extension(expression)
.split(['.', '/', '\\'])
.filter(|segment| !segment.is_empty() && *segment != "*")
.collect();
if segments.is_empty() {
String::from(expression)
} else {
segments.join(".")
}
}
#[cfg(test)]
mod tests {
use super::normalize_module_path;
#[test]
fn keeps_a_dotted_module_name() {
assert_eq!(normalize_module_path("a.b.c"), "a.b.c");
}
#[test]
fn keeps_an_unknown_extension_on_a_two_segment_name() {
assert_eq!(normalize_module_path("os.path"), "os.path");
}
#[test]
fn strips_a_known_extension_ignoring_its_case() {
assert_eq!(normalize_module_path("util.PY"), "util");
}
#[test]
fn keeps_a_known_extension_when_the_name_has_two_dots() {
assert_eq!(normalize_module_path("a.b.py"), "a.b.py");
}
#[test]
fn turns_a_file_path_into_a_dotted_module() {
assert_eq!(normalize_module_path("./lib/util.js"), "lib.util");
assert_eq!(normalize_module_path("lib\\util"), "lib.util");
}
#[test]
fn strips_only_the_last_extension_of_a_file_path() {
assert_eq!(normalize_module_path("lib/types.d.ts"), "lib.types.d");
}
#[test]
fn keeps_a_dotfile_name_as_its_only_segment() {
assert_eq!(normalize_module_path("lib/.py"), "lib.py");
}
#[test]
fn drops_wildcard_segments() {
assert_eq!(normalize_module_path("x.*"), "x");
}
#[test]
fn returns_the_expression_when_no_segment_survives() {
assert_eq!(normalize_module_path("..."), "...");
assert_eq!(normalize_module_path("*"), "*");
assert_eq!(normalize_module_path(""), "");
}
}