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}
20
21impl CrateReference {
22    pub fn new(name: String) -> Self {
23        Self {
24            name,
25            features: HashSet::new(),
26            used_in: HashSet::new(),
27            is_path_dependency: false,
28            path: None,
29            publish: None,
30        }
31    }
32
33    pub fn with_path(name: String, path: String) -> Self {
34        Self {
35            name,
36            features: HashSet::new(),
37            used_in: HashSet::new(),
38            is_path_dependency: true,
39            path: Some(path),
40            publish: None,
41        }
42    }
43
44    pub fn add_usage(&mut self, path: PathBuf) {
45        self.used_in.insert(path);
46    }
47
48    pub fn add_feature(&mut self, feature: String) {
49        self.features.insert(feature);
50    }
51
52    pub fn usage_count(&self) -> usize {
53        self.used_in.len()
54    }
55
56    pub fn set_as_path_dependency(&mut self, path: String) {
57        self.is_path_dependency = true;
58        self.path = Some(path);
59    }
60
61    pub fn set_publish(&mut self, publish: bool) {
62        self.publish = Some(publish);
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69    use std::path::Path;
70
71    #[test]
72    fn test_new_crate_reference() {
73        let crate_ref = CrateReference::new("test_crate".to_string());
74        assert_eq!(crate_ref.name, "test_crate");
75        assert!(crate_ref.features.is_empty());
76        assert!(crate_ref.used_in.is_empty());
77        assert!(!crate_ref.is_path_dependency);
78        assert!(crate_ref.path.is_none());
79        assert!(crate_ref.publish.is_none());
80    }
81
82    #[test]
83    fn test_with_path() {
84        let crate_ref =
85            CrateReference::with_path("test_crate".to_string(), "../test_crate".to_string());
86        assert_eq!(crate_ref.name, "test_crate");
87        assert!(crate_ref.features.is_empty());
88        assert!(crate_ref.used_in.is_empty());
89        assert!(crate_ref.is_path_dependency);
90        assert_eq!(crate_ref.path, Some("../test_crate".to_string()));
91        assert!(crate_ref.publish.is_none());
92    }
93
94    #[test]
95    fn test_add_usage() {
96        let mut crate_ref = CrateReference::new("test_crate".to_string());
97        let path = Path::new("/test/path.rs").to_path_buf();
98        crate_ref.add_usage(path.clone());
99        assert!(crate_ref.used_in.contains(&path));
100        assert_eq!(crate_ref.usage_count(), 1);
101    }
102
103    #[test]
104    fn test_add_feature() {
105        let mut crate_ref = CrateReference::new("test_crate".to_string());
106        crate_ref.add_feature("test_feature".to_string());
107        assert!(crate_ref.features.contains("test_feature"));
108    }
109
110    #[test]
111    fn test_set_as_path_dependency() {
112        let mut crate_ref = CrateReference::new("test_crate".to_string());
113        crate_ref.set_as_path_dependency("../test_crate".to_string());
114        assert!(crate_ref.is_path_dependency);
115        assert_eq!(crate_ref.path, Some("../test_crate".to_string()));
116    }
117
118    #[test]
119    fn test_set_publish() {
120        let mut crate_ref = CrateReference::new("test_crate".to_string());
121        crate_ref.set_publish(false);
122        assert_eq!(crate_ref.publish, Some(false));
123    }
124}