aboutsummaryrefslogtreecommitdiff
path: root/development/tools/cargo-workspace2/src/models/_crate.rs
blob: 68d2baad2bad16bd2566eb6a6d90342e23c70736 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use crate::models::{CargoCrate, CrateId, DepGraph};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::{
    cmp::{self, Eq, Ord, PartialEq, PartialOrd},
    collections::BTreeSet,
    path::PathBuf,
};

static ID_CTR: AtomicUsize = AtomicUsize::new(0);

/// A crate in a cargo workspace
///
/// Has a name, path (stored as the offset of the root), and set of
/// dependencies inside the workspace.  To get the dependents of this
/// crate, query the dependency graph with the set of other crate IDs.
#[derive(Clone, Debug)]
pub struct Crate {
    /// Numeric Id of this crate
    pub id: CrateId,
    /// Package name, not the folder name
    pub name: String,
    /// Path offset of the workspace root
    pub cc: CargoCrate,
    /// List of dependencies this crate has inside this workspace
    pub dependencies: BTreeSet<CrateId>,
}

impl PartialEq for Crate {
    fn eq(&self, other: &Self) -> bool {
        self.id == other.id
    }
}

impl Eq for Crate {}

impl Ord for Crate {
    fn cmp(&self, other: &Self) -> cmp::Ordering {
        self.id.cmp(&other.id)
    }
}

impl PartialOrd for Crate {
    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
        Some(self.cmp(other))
    }
}

/// Increment the monotonicly increasing Id
fn incr_id() -> usize {
    ID_CTR.fetch_add(1, Ordering::Relaxed)
}

impl Crate {
    pub fn new(cc: CargoCrate) -> Self {
        Self {
            id: incr_id(),
            name: cc.name(),
            cc,
            dependencies: BTreeSet::default(),
        }
    }

    /// Call this function once all crates have been loaded into scope
    pub fn process(&mut self, g: &DepGraph) {
        let deps: Vec<_> = self
            .cc
            .dependencies
            .iter()
            .filter_map(|d| g.find_crate(&d.name))
            .collect();

        deps.into_iter().for_each(|cid| self.add_dependency(cid));
    }

    /// Get the crate name
    pub fn name(&self) -> &String {
        &self.name
    }

    /// Get the crate path
    pub fn path(&self) -> &PathBuf {
        &self.cc.path
    }

    /// Get the current version
    pub fn version(&self) -> String {
        self.cc.version()
    }

    /// Add a dependency of this crate
    pub fn add_dependency(&mut self, id: CrateId) {
        self.dependencies.insert(id);
    }

    /// Check if this crate has a particular dependency
    pub fn has_dependency(&self, id: CrateId) -> bool {
        self.dependencies.contains(&id)
    }

    pub fn change_dependency(&mut self, dep: &String, new_ver: &String) {
        self.cc.change_dep(dep, new_ver);
    }

    /// Publish a new version of this crate
    pub fn publish(&mut self, new_version: String) {
        self.cc.set_version(new_version);
    }

    pub fn sync(&mut self) {
        self.cc.sync();
    }
}