use std::collections::BTreeSet;
pub(crate) fn parse_path(raw: &str) -> Vec<String> {
raw.split("::")
.map(str::trim)
.filter(|segment| !segment.is_empty())
.map(str::to_owned)
.collect()
}
pub(crate) fn parse_path_list(raw_entries: &[String]) -> BTreeSet<Vec<String>> {
raw_entries
.iter()
.map(|entry| parse_path(entry))
.filter(|parsed| !parsed.is_empty())
.collect()
}
pub(crate) fn merge_with_builtins(
builtin: &[&str],
extras: &BTreeSet<Vec<String>>,
) -> BTreeSet<Vec<String>> {
builtin
.iter()
.map(|name| vec![(*name).to_owned()])
.chain(extras.iter().cloned())
.collect()
}
pub(crate) fn matches_any(invocation: &rustc_ast::Path, entries: &BTreeSet<Vec<String>>) -> bool {
entries.iter().any(|entry| entry_matches(entry, invocation))
}
pub(crate) fn entry_matches(entry: &[String], invocation: &rustc_ast::Path) -> bool {
let segments = &invocation.segments;
if entry.is_empty() || segments.is_empty() {
return false;
}
if entry.len() == 1 {
return segments
.last()
.is_some_and(|segment| segment.ident.name.as_str() == entry[0]);
}
if segments.len() < entry.len() {
return false;
}
let start = segments.len() - entry.len();
segments[start..]
.iter()
.zip(entry.iter())
.all(|(segment, entry_segment)| segment.ident.name.as_str() == entry_segment.as_str())
}