cargo_autodd/models/
crate_reference.rs

1use std::collections::HashSet;
2use std::path::PathBuf;
3
4/// A reference to a crate and its usage within the project
5#[derive(Debug, Clone)]
6pub struct CrateReference {
7    /// Name of the crate
8    pub name: String,
9    /// Set of features used by this crate
10    pub features: HashSet<String>,
11    /// Set of file paths where this crate is used
12    pub used_in: HashSet<PathBuf>,
13    /// Whether this crate is a path dependency (internal crate)
14    pub is_path_dependency: bool,
15    /// Path to the internal crate if it's a path dependency
16    pub path: Option<String>,
17    /// Whether this crate is marked as not publishable
18    pub publish: Option<bool>,
19    /// Whether this crate is a dev-dependency (used only in tests)
20    pub is_dev_dependency: bool,
21}
22
23impl CrateReference {
24    pub fn new(name: String) -> Self {
25        Self {
26            name,
27            features: HashSet::new(),
28            used_in: HashSet::new(),
29            is_path_dependency: false,
30            path: None,
31            publish: None,
32            is_dev_dependency: false,
33        }
34    }
35
36    pub fn with_path(name: String, path: String) -> Self {
37        Self {
38            name,
39            features: HashSet::new(),
40            used_in: HashSet::new(),
41            is_path_dependency: true,
42            path: Some(path),
43            publish: None,
44            is_dev_dependency: false,
45        }
46    }
47
48    pub fn new_dev(name: String) -> Self {
49        Self {
50            name,
51            features: HashSet::new(),
52            used_in: HashSet::new(),
53            is_path_dependency: false,
54            path: None,
55            publish: None,
56            is_dev_dependency: true,
57        }
58    }
59
60    pub fn add_usage(&mut self, path: PathBuf) {
61        self.used_in.insert(path);
62    }
63
64    pub fn add_feature(&mut self, feature: String) {
65        self.features.insert(feature);
66    }
67
68    pub fn usage_count(&self) -> usize {
69        self.used_in.len()
70    }
71
72    pub fn set_as_path_dependency(&mut self, path: String) {
73        self.is_path_dependency = true;
74        self.path = Some(path);
75    }
76
77    pub fn set_publish(&mut self, publish: bool) {
78        self.publish = Some(publish);
79    }
80
81    pub fn set_dev_dependency(&mut self, is_dev: bool) {
82        self.is_dev_dependency = is_dev;
83    }
84}
85
86#[cfg(test)]
87mod tests {
88    use super::*;
89    use std::path::Path;
90
91    #[test]
92    fn test_new_crate_reference() {
93        let crate_ref = CrateReference::new("test_crate".to_string());
94        assert_eq!(crate_ref.name, "test_crate");
95        assert!(crate_ref.features.is_empty());
96        assert!(crate_ref.used_in.is_empty());
97        assert!(!crate_ref.is_path_dependency);
98        assert!(crate_ref.path.is_none());
99        assert!(crate_ref.publish.is_none());
100        assert!(!crate_ref.is_dev_dependency);
101    }
102
103    #[test]
104    fn test_with_path() {
105        let crate_ref =
106            CrateReference::with_path("test_crate".to_string(), "../test_crate".to_string());
107        assert_eq!(crate_ref.name, "test_crate");
108        assert!(crate_ref.features.is_empty());
109        assert!(crate_ref.used_in.is_empty());
110        assert!(crate_ref.is_path_dependency);
111        assert_eq!(crate_ref.path, Some("../test_crate".to_string()));
112        assert!(crate_ref.publish.is_none());
113    }
114
115    #[test]
116    fn test_add_usage() {
117        let mut crate_ref = CrateReference::new("test_crate".to_string());
118        let path = Path::new("/test/path.rs").to_path_buf();
119        crate_ref.add_usage(path.clone());
120        assert!(crate_ref.used_in.contains(&path));
121        assert_eq!(crate_ref.usage_count(), 1);
122    }
123
124    #[test]
125    fn test_add_feature() {
126        let mut crate_ref = CrateReference::new("test_crate".to_string());
127        crate_ref.add_feature("test_feature".to_string());
128        assert!(crate_ref.features.contains("test_feature"));
129    }
130
131    #[test]
132    fn test_set_as_path_dependency() {
133        let mut crate_ref = CrateReference::new("test_crate".to_string());
134        crate_ref.set_as_path_dependency("../test_crate".to_string());
135        assert!(crate_ref.is_path_dependency);
136        assert_eq!(crate_ref.path, Some("../test_crate".to_string()));
137    }
138
139    #[test]
140    fn test_set_publish() {
141        let mut crate_ref = CrateReference::new("test_crate".to_string());
142        crate_ref.set_publish(false);
143        assert_eq!(crate_ref.publish, Some(false));
144    }
145
146    #[test]
147    fn test_new_dev() {
148        let crate_ref = CrateReference::new_dev("test_crate".to_string());
149        assert_eq!(crate_ref.name, "test_crate");
150        assert!(crate_ref.is_dev_dependency);
151        assert!(!crate_ref.is_path_dependency);
152    }
153
154    #[test]
155    fn test_set_dev_dependency() {
156        let mut crate_ref = CrateReference::new("test_crate".to_string());
157        assert!(!crate_ref.is_dev_dependency);
158        crate_ref.set_dev_dependency(true);
159        assert!(crate_ref.is_dev_dependency);
160    }
161}