aboutsummaryrefslogtreecommitdiff
path: root/development/tools/cargo-workspace2/src/query/executor.rs
diff options
context:
space:
mode:
Diffstat (limited to 'development/tools/cargo-workspace2/src/query/executor.rs')
-rw-r--r--development/tools/cargo-workspace2/src/query/executor.rs83
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!(),
+ }
+}