use crate::v2;
#[derive(Clone, Copy)]
pub(crate) struct Scope<'a> {
pub package: &'a v2::Package,
pub others: &'a [&'a v2::Package],
}
impl<'a> Scope<'a> {
pub fn resolve(
&self,
home: &'a v2::Package,
reference: &str,
) -> Option<(&'a v2::Decl, &'a v2::Package)> {
match reference.rsplit_once('.') {
Some((package, member)) => self
.packages()
.find(|candidate| candidate.name == package)
.and_then(|candidate| {
candidate
.decls
.iter()
.find(|decl| decl.name == member)
.map(|decl| (decl, candidate))
}),
None => home
.decls
.iter()
.find(|decl| decl.name == reference)
.map(|decl| (decl, home)),
}
}
pub fn packages(&self) -> impl Iterator<Item = &'a v2::Package> {
std::iter::once(self.package).chain(self.others.iter().copied())
}
pub fn projection_others(&self, home: &v2::Package) -> Vec<&'a v2::Package> {
self.packages()
.filter(|candidate| candidate.name != home.name)
.collect()
}
}
pub(crate) fn is_foreign(reference: &str) -> bool {
reference.contains('.')
}