aboutsummaryrefslogtreecommitdiff
path: root/development/tools/cargo-workspace2/src/models/graph.rs
diff options
context:
space:
mode:
Diffstat (limited to 'development/tools/cargo-workspace2/src/models/graph.rs')
-rw-r--r--development/tools/cargo-workspace2/src/models/graph.rs78
1 files changed, 78 insertions, 0 deletions
diff --git a/development/tools/cargo-workspace2/src/models/graph.rs b/development/tools/cargo-workspace2/src/models/graph.rs
new file mode 100644
index 000000000000..867c463fb1e3
--- /dev/null
+++ b/development/tools/cargo-workspace2/src/models/graph.rs
@@ -0,0 +1,78 @@
+use crate::models::{CargoCrate, Crate, CrateId};
+use std::collections::{BTreeMap, BTreeSet};
+use std::path::PathBuf;
+
+/// Dependency graph in a workspace
+pub struct DepGraph {
+ /// Mapping of crates in the workspace
+ members: BTreeMap<CrateId, Crate>,
+ /// Map of crates and the members that depend on them
+ dependents: BTreeMap<CrateId, BTreeSet<CrateId>>,
+}
+
+impl DepGraph {
+ /// Create a new, empty dependency graph
+ pub fn new() -> Self {
+ Self {
+ members: Default::default(),
+ dependents: Default::default(),
+ }
+ }
+
+ pub fn add_crate(&mut self, cc: CargoCrate) {
+ let cc = Crate::new(cc);
+ self.members.insert(cc.id, cc);
+ }
+
+ /// Cache the dependents graph for all crates
+ pub fn finalise(&mut self) {
+ let mut members = self.members.clone();
+ members.iter_mut().for_each(|(_, c)| c.process(&self));
+
+ members.iter().for_each(|(id, _crate)| {
+ _crate.dependencies.iter().for_each(|dep_id| {
+ self.dependents.entry(*dep_id).or_default().insert(*id);
+ });
+ });
+ let _ = std::mem::replace(&mut self.members, members);
+ }
+
+ /// Get a crate by ID
+ pub fn get_crate(&self, id: CrateId) -> &Crate {
+ self.members.get(&id).as_ref().unwrap()
+ }
+
+ /// Get mutable access to a crate by ID
+ pub fn mut_crate(&mut self, id: CrateId) -> &mut Crate {
+ self.members.get_mut(&id).unwrap()
+ }
+
+ /// Find a crate via it's name
+ pub fn find_crate(&self, name: &String) -> Option<CrateId> {
+ self.members
+ .iter()
+ .find(|(_, c)| c.name() == name)
+ .map(|(id, _)| *id)
+ }
+
+ /// Find a crate by it's path-offset in the workspace
+ pub fn find_crate_by_path(&self, name: &String) -> Option<CrateId> {
+ self.members
+ .iter()
+ .find(|(_, c)| c.path() == &PathBuf::new().join(name))
+ .map(|(id, _)| *id)
+ }
+
+ /// Get a crate's dependents
+ pub fn get_dependents(&self, id: CrateId) -> Vec<CrateId> {
+ self.dependents
+ .get(&id)
+ .as_ref()
+ .map(|set| set.iter().cloned().collect())
+ .unwrap_or(vec![])
+ }
+
+ pub fn get_all(&self) -> Vec<&Crate> {
+ self.members.iter().map(|(_, c)| c).collect()
+ }
+}