use std::path::Path;
use crate::core::moniker::{Moniker, MonikerBuilder};
use super::kinds;
pub(super) fn compute_module_moniker(anchor: &Moniker, uri: &str) -> Moniker {
let (pkg_pieces, module_name) = split_path(uri);
let mut b = MonikerBuilder::from_view(anchor.as_view());
b.segment(crate::lang::kinds::LANG, b"python");
for piece in pkg_pieces {
b.segment(kinds::PACKAGE, piece.as_bytes());
}
b.segment(kinds::MODULE, module_name.as_bytes());
b.build()
}
fn split_path(uri: &str) -> (Vec<&str>, &str) {
let after_scheme = uri.split("://").last().unwrap_or(uri);
let pieces: Vec<&str> = after_scheme.split('/').filter(|s| !s.is_empty()).collect();
if pieces.is_empty() {
return (Vec::new(), "");
}
let (last, head) = pieces.split_last().expect("non-empty");
(head.to_vec(), strip_py_suffix(last))
}
fn strip_py_suffix(name: &str) -> &str {
Path::new(name)
.file_stem()
.and_then(|s| s.to_str())
.unwrap_or(name)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn split_path_strips_extension() {
let (pkg, name) = split_path("foo.py");
assert!(pkg.is_empty());
assert_eq!(name, "foo");
}
#[test]
fn split_path_keeps_init_module_name() {
let (pkg, name) = split_path("acme/__init__.py");
assert_eq!(pkg, vec!["acme"]);
assert_eq!(name, "__init__");
}
#[test]
fn split_path_emits_package_chain() {
let (pkg, name) = split_path("acme/util/text.py");
assert_eq!(pkg, vec!["acme", "util"]);
assert_eq!(name, "text");
}
}