use super::impact::SeedKind;
use super::index::GraphIndex;
use super::member::{self, MemberCandidate, MemberSeedResolution};
use super::symbol::{resolve_symbol, Resolution};
pub fn looks_like_file_path(arg: &str) -> bool {
if arg.contains('/') {
return true;
}
match arg.rfind('.') {
Some(pos) => {
let ext = &arg[pos + 1..];
!ext.is_empty() && ext.chars().all(|c| c.is_ascii_alphanumeric())
}
None => false,
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum SeedResolution {
Resolved {
kind: SeedKind,
ids: Vec<String>,
},
Ambiguous {
kind: SeedKind,
ids: Vec<String>,
},
NotFound {
kind: SeedKind,
},
MemberAmbiguous(Vec<MemberCandidate>),
}
fn member_fallback(index: &GraphIndex, arg: &str, not_found_kind: SeedKind) -> SeedResolution {
match member::resolve_member_seed(index, arg) {
MemberSeedResolution::Resolved(id) => SeedResolution::Resolved {
kind: SeedKind::Symbol,
ids: vec![id],
},
MemberSeedResolution::Ambiguous(candidates) => SeedResolution::MemberAmbiguous(candidates),
MemberSeedResolution::NotFound => SeedResolution::NotFound {
kind: not_found_kind,
},
}
}
pub fn resolve_impact_seed(index: &GraphIndex, arg: &str) -> SeedResolution {
if looks_like_file_path(arg) {
return match index.by_file.get(arg) {
Some(ids) if !ids.is_empty() => SeedResolution::Resolved {
kind: SeedKind::File,
ids: ids
.iter()
.map(|&i| index.graph.defs[i].id.clone())
.collect(),
},
_ => member_fallback(index, arg, SeedKind::File),
};
}
match resolve_symbol(index, arg) {
Resolution::Resolved(id) => SeedResolution::Resolved {
kind: SeedKind::Symbol,
ids: vec![id],
},
Resolution::Ambiguous(ids) => SeedResolution::Ambiguous {
kind: SeedKind::Symbol,
ids,
},
Resolution::NotFound => member_fallback(index, arg, SeedKind::Symbol),
}
}