diff options
Diffstat (limited to 'development/tools/cargo-workspace2/src/query/executor.rs')
-rw-r--r-- | development/tools/cargo-workspace2/src/query/executor.rs | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/development/tools/cargo-workspace2/src/query/executor.rs b/development/tools/cargo-workspace2/src/query/executor.rs new file mode 100644 index 000000000000..da67324de4c0 --- /dev/null +++ b/development/tools/cargo-workspace2/src/query/executor.rs @@ -0,0 +1,83 @@ +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!(), + } +} |