My personal project and infrastructure archive
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.
 
 
 
 
 
 
nomicon/development/tools/cargo-workspace2/src/query/executor.rs

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!(),
}
}