You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
83 lines
2.5 KiB
83 lines
2.5 KiB
use super::{Constraint, DepConstraint};
|
|
use crate::models::{CrateId, DepGraph};
|
|
use std::collections::BTreeSet;
|
|
|
|
/// Execute a simple set query
|
|
pub(crate) fn set(crates: &Vec<String>, g: &DepGraph) -> Vec<CrateId> {
|
|
crates
|
|
.iter()
|
|
.filter_map(|name| match g.find_crate(name) {
|
|
None => {
|
|
eprintln!("[ERROR]: Unable to find crate: `{}`", name);
|
|
None
|
|
}
|
|
some => some,
|
|
})
|
|
.collect()
|
|
}
|
|
|
|
/// Execute a search query on the dependency graph
|
|
pub(crate) fn deps(mut deps: Vec<DepConstraint>, g: &DepGraph) -> Vec<CrateId> {
|
|
// Parse the anchor point (first crate)
|
|
let DepConstraint {
|
|
ref _crate,
|
|
ref constraint,
|
|
} = deps.remove(0);
|
|
let init_id = get_crate_error(_crate, g);
|
|
|
|
// Get it's dependents
|
|
let mut dependents: BTreeSet<_> = match constraint {
|
|
Constraint::Initial(true) => g.get_dependents(init_id).into_iter().collect(),
|
|
Constraint::Initial(false) => g
|
|
.get_all()
|
|
.iter()
|
|
.filter(|c| c.has_dependency(init_id))
|
|
.map(|c| c.id)
|
|
.collect(),
|
|
_ => {
|
|
eprintln!("Invalid initial constraint! Only `<` and `!<` are allowed!");
|
|
std::process::exit(2);
|
|
}
|
|
};
|
|
|
|
// Then loop over all other constraints and subtract crates from
|
|
// the dependents set until all constraints are met.
|
|
deps.reverse();
|
|
while let Some(dc) = deps.pop() {
|
|
let DepConstraint {
|
|
ref _crate,
|
|
ref constraint,
|
|
} = dc;
|
|
|
|
let id = get_crate_error(_crate, g);
|
|
let ldeps = g.get_dependents(id);
|
|
dependents = apply_constraint(dependents, ldeps, constraint);
|
|
}
|
|
|
|
dependents.into_iter().collect()
|
|
}
|
|
|
|
fn get_crate_error(_crate: &String, g: &DepGraph) -> CrateId {
|
|
match g.find_crate(&_crate.trim().to_string()) {
|
|
Some(id) => id,
|
|
None => {
|
|
eprintln!("[ERROR]: Crate `{}` not found in workspace!", _crate);
|
|
std::process::exit(2);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn apply_constraint(
|
|
init: BTreeSet<CrateId>,
|
|
cmp: Vec<CrateId>,
|
|
cnd: &Constraint,
|
|
) -> BTreeSet<CrateId> {
|
|
let cmp: BTreeSet<CrateId> = cmp.into_iter().collect();
|
|
let init = init.into_iter();
|
|
match cnd {
|
|
Constraint::And(true) => init.filter(|id| cmp.contains(id)).collect(),
|
|
Constraint::And(false) => init.filter(|id| !cmp.contains(id)).collect(),
|
|
Constraint::Or => init.chain(cmp.into_iter()).collect(),
|
|
_ => todo!(),
|
|
}
|
|
}
|
|
|