use crate::loader::PackageMatchSemantics;
#[must_use]
pub(crate) fn import_matches_package(
imported: &str,
needle: &str,
semantics: &PackageMatchSemantics,
) -> bool {
if needle.is_empty() {
return false;
}
let imported = semantics
.strip_import_prefixes
.iter()
.find_map(|prefix| imported.strip_prefix(prefix))
.unwrap_or(imported);
if imported == needle {
return true;
}
let stripped = semantics
.strip_import_suffixes
.iter()
.find_map(|suffix| imported.strip_suffix(suffix))
.unwrap_or(imported);
if stripped == needle {
return true;
}
semantics.package_separators.iter().any(|separator| {
starts_with_package_separator(imported, needle, separator)
|| (stripped != imported && starts_with_package_separator(stripped, needle, separator))
})
}
fn starts_with_package_separator(imported: &str, needle: &str, separator: &str) -> bool {
!separator.is_empty()
&& imported.len() > needle.len() + separator.len()
&& imported.starts_with(needle)
&& imported[needle.len()..].starts_with(separator)
}
#[must_use]
pub(crate) fn call_candidate_matches_package_tail(
candidate: &str,
needle: &str,
semantics: &PackageMatchSemantics,
) -> bool {
let Some(binding) = semantics.call_qualifier_from_package_tail.as_ref() else {
return false;
};
if candidate.is_empty() || binding.package_separator.is_empty() {
return false;
}
let Some((head, tail)) = needle.rsplit_once(binding.package_separator.as_str()) else {
return false;
};
if head.is_empty() || tail.is_empty() {
return false;
}
let candidate_head = binding
.call_separators
.iter()
.filter_map(|separator| candidate.find(separator).map(|index| (index, separator.len())))
.min_by_key(|(index, _)| *index)
.map_or(candidate, |(index, _)| &candidate[..index])
.trim();
!candidate_head.is_empty() && candidate_head == tail
}
#[cfg(test)]
#[path = "pkg_tests.rs"]
mod tests;