diff options
Diffstat (limited to 'development/tools/cargo-workspace2/src/models/graph.rs')
-rw-r--r-- | development/tools/cargo-workspace2/src/models/graph.rs | 78 |
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() + } +} |