Skip to main content

cargo_workspace2/models/
_crate.rs

1use crate::models::{CargoCrate, CrateId, DepGraph};
2use std::sync::atomic::{AtomicUsize, Ordering};
3use std::{
4    cmp::{self, Eq, Ord, PartialEq, PartialOrd},
5    collections::BTreeSet,
6    path::PathBuf,
7};
8
9static ID_CTR: AtomicUsize = AtomicUsize::new(0);
10
11/// A crate in a cargo workspace
12///
13/// Has a name, path (stored as the offset of the root), and set of
14/// dependencies inside the workspace.  To get the dependents of this
15/// crate, query the dependency graph with the set of other crate IDs.
16#[derive(Clone, Debug)]
17pub struct Crate {
18    /// Numeric Id of this crate
19    pub id: CrateId,
20    /// Package name, not the folder name
21    pub name: String,
22    /// Path offset of the workspace root
23    pub cc: CargoCrate,
24    /// List of dependencies this crate has inside this workspace
25    pub dependencies: BTreeSet<CrateId>,
26}
27
28impl PartialEq for Crate {
29    fn eq(&self, other: &Self) -> bool {
30        self.id == other.id
31    }
32}
33
34impl Eq for Crate {}
35
36impl Ord for Crate {
37    fn cmp(&self, other: &Self) -> cmp::Ordering {
38        self.id.cmp(&other.id)
39    }
40}
41
42impl PartialOrd for Crate {
43    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
44        Some(self.cmp(other))
45    }
46}
47
48/// Increment the monotonicly increasing Id
49fn incr_id() -> usize {
50    ID_CTR.fetch_add(1, Ordering::Relaxed)
51}
52
53impl Crate {
54    pub fn new(cc: CargoCrate) -> Self {
55        Self {
56            id: incr_id(),
57            name: cc.name(),
58            cc,
59            dependencies: BTreeSet::default(),
60        }
61    }
62
63    /// Call this function once all crates have been loaded into scope
64    pub fn process(&mut self, g: &DepGraph) {
65        let deps: Vec<_> = self
66            .cc
67            .dependencies
68            .iter()
69            .filter_map(|d| g.find_crate(&d.name))
70            .collect();
71
72        deps.into_iter().for_each(|cid| self.add_dependency(cid));
73    }
74
75    /// Get the crate name
76    pub fn name(&self) -> &String {
77        &self.name
78    }
79
80    /// Get the crate path
81    pub fn path(&self) -> &PathBuf {
82        &self.cc.path
83    }
84
85    /// Get the current version
86    pub fn version(&self) -> String {
87        self.cc.version()
88    }
89
90    /// Add a dependency of this crate
91    pub fn add_dependency(&mut self, id: CrateId) {
92        self.dependencies.insert(id);
93    }
94
95    /// Check if this crate has a particular dependency
96    pub fn has_dependency(&self, id: CrateId) -> bool {
97        self.dependencies.contains(&id)
98    }
99
100    pub fn change_dependency(&mut self, dep: &String, new_ver: &String) {
101        self.cc.change_dep(dep, new_ver);
102    }
103
104    /// Publish a new version of this crate
105    pub fn publish(&mut self, new_version: String) {
106        self.cc.set_version(new_version);
107    }
108
109    pub fn sync(&mut self) {
110        self.cc.sync();
111    }
112}