py_import_helper/registry/
mod.rs1pub mod constants;
8
9use constants::{COMMON_THIRD_PARTY_PACKAGES, PYTHON_STDLIB_MODULES};
10use std::collections::HashSet;
11
12#[derive(Debug, Clone)]
18pub struct PackageRegistry {
19 stdlib_packages: HashSet<String>,
21 third_party_packages: HashSet<String>,
23}
24
25impl PackageRegistry {
26 #[must_use]
28 pub fn new() -> Self {
29 Self {
30 stdlib_packages: Self::default_stdlib_packages(),
31 third_party_packages: Self::default_third_party_packages(),
32 }
33 }
34
35 #[must_use]
37 pub fn is_stdlib(&self, package: &str) -> bool {
38 self.stdlib_packages.contains(package)
39 }
40
41 #[must_use]
43 pub fn is_third_party(&self, package: &str) -> bool {
44 self.third_party_packages.contains(package)
45 }
46
47 pub fn add_stdlib_package(&mut self, package: impl Into<String>) -> &mut Self {
58 self.stdlib_packages.insert(package.into());
59 self
60 }
61
62 pub fn add_third_party_package(&mut self, package: impl Into<String>) -> &mut Self {
73 self.third_party_packages.insert(package.into());
74 self
75 }
76
77 pub fn remove_stdlib_package(&mut self, package: &str) -> &mut Self {
79 self.stdlib_packages.remove(package);
80 self
81 }
82
83 pub fn remove_third_party_package(&mut self, package: &str) -> &mut Self {
85 self.third_party_packages.remove(package);
86 self
87 }
88
89 pub fn clear_stdlib_packages(&mut self) -> &mut Self {
91 self.stdlib_packages.clear();
92 self
93 }
94
95 pub fn clear_third_party_packages(&mut self) -> &mut Self {
97 self.third_party_packages.clear();
98 self
99 }
100
101 pub fn add_stdlib_packages(&mut self, packages: &[&str]) -> &mut Self {
103 for package in packages {
104 self.stdlib_packages.insert((*package).to_string());
105 }
106 self
107 }
108
109 pub fn add_third_party_packages(&mut self, packages: &[&str]) -> &mut Self {
111 for package in packages {
112 self.third_party_packages.insert((*package).to_string());
113 }
114 self
115 }
116
117 fn default_stdlib_packages() -> HashSet<String> {
119 PYTHON_STDLIB_MODULES
120 .iter()
121 .map(|s| (*s).to_string())
122 .collect()
123 }
124
125 fn default_third_party_packages() -> HashSet<String> {
127 COMMON_THIRD_PARTY_PACKAGES
128 .iter()
129 .map(|s| (*s).to_string())
130 .collect()
131 }
132
133 pub fn reset_stdlib_to_defaults(&mut self) -> &mut Self {
135 self.stdlib_packages = Self::default_stdlib_packages();
136 self
137 }
138
139 pub fn reset_third_party_to_defaults(&mut self) -> &mut Self {
141 self.third_party_packages = Self::default_third_party_packages();
142 self
143 }
144
145 #[must_use]
147 pub fn count_stdlib_packages(&self) -> usize {
148 self.stdlib_packages.len()
149 }
150
151 #[must_use]
153 pub fn count_third_party_packages(&self) -> usize {
154 self.third_party_packages.len()
155 }
156}
157
158impl Default for PackageRegistry {
159 fn default() -> Self {
160 Self::new()
161 }
162}
163
164#[cfg(test)]
165mod tests {
166 use super::*;
167
168 #[test]
169 fn test_default_registry() {
170 let registry = PackageRegistry::new();
171 assert!(registry.is_stdlib("typing"));
172 assert!(registry.is_stdlib("os"));
173 assert!(registry.is_third_party("pydantic"));
174 assert!(registry.is_third_party("pytest"));
175 }
176
177 #[test]
178 fn test_add_stdlib_package() {
179 let mut registry = PackageRegistry::new();
180 registry.add_stdlib_package("my_custom_stdlib");
181 assert!(registry.is_stdlib("my_custom_stdlib"));
182 }
183
184 #[test]
185 fn test_add_third_party_package() {
186 let mut registry = PackageRegistry::new();
187 registry.add_third_party_package("my_company_lib");
188 assert!(registry.is_third_party("my_company_lib"));
189 }
190
191 #[test]
192 fn test_remove_packages() {
193 let mut registry = PackageRegistry::new();
194 registry.remove_stdlib_package("typing");
195 assert!(!registry.is_stdlib("typing"));
196 }
197
198 #[test]
199 fn test_bulk_add() {
200 let mut registry = PackageRegistry::new();
201 registry.add_stdlib_packages(&["pkg1", "pkg2", "pkg3"]);
202 assert!(registry.is_stdlib("pkg1"));
203 assert!(registry.is_stdlib("pkg2"));
204 assert!(registry.is_stdlib("pkg3"));
205 }
206
207 #[test]
208 fn test_reset_to_defaults() {
209 let mut registry = PackageRegistry::new();
210 registry.clear_stdlib_packages();
211 assert_eq!(registry.count_stdlib_packages(), 0);
212
213 registry.reset_stdlib_to_defaults();
214 assert!(registry.count_stdlib_packages() > 0);
215 assert!(registry.is_stdlib("typing"));
216 }
217
218 #[test]
219 fn test_chaining() {
220 let mut registry = PackageRegistry::new();
221 registry
222 .add_stdlib_package("pkg1")
223 .add_stdlib_package("pkg2")
224 .add_third_party_package("lib1");
225
226 assert!(registry.is_stdlib("pkg1"));
227 assert!(registry.is_stdlib("pkg2"));
228 assert!(registry.is_third_party("lib1"));
229 }
230}