codegraph_python/
config.rs1#[derive(Debug, Clone)]
3pub struct ParserConfig {
4 pub include_private: bool,
6
7 pub include_tests: bool,
9
10 pub parse_docs: bool,
12
13 pub max_file_size: usize,
15
16 pub file_extensions: Vec<String>,
18
19 pub exclude_dirs: Vec<String>,
21
22 pub parallel: bool,
24
25 pub num_threads: Option<usize>,
27}
28
29impl Default for ParserConfig {
30 fn default() -> Self {
31 Self {
32 include_private: true,
33 include_tests: true,
34 parse_docs: true,
35 max_file_size: 10 * 1024 * 1024, file_extensions: vec![".py".to_string()],
37 exclude_dirs: vec![
38 "__pycache__".to_string(),
39 ".git".to_string(),
40 ".venv".to_string(),
41 "venv".to_string(),
42 "env".to_string(),
43 ".tox".to_string(),
44 "dist".to_string(),
45 "build".to_string(),
46 ".eggs".to_string(),
47 "*.egg-info".to_string(),
48 ],
49 parallel: false,
50 num_threads: None,
51 }
52 }
53}
54
55impl ParserConfig {
56 pub fn validate(&self) -> Result<(), String> {
58 if let Some(threads) = self.num_threads {
59 if threads == 0 {
60 return Err("num_threads must be greater than 0".to_string());
61 }
62 }
63
64 if self.max_file_size == 0 {
65 return Err("max_file_size must be greater than 0".to_string());
66 }
67
68 if self.file_extensions.is_empty() {
69 return Err("file_extensions cannot be empty".to_string());
70 }
71
72 Ok(())
73 }
74
75 pub fn should_parse_extension(&self, extension: &str) -> bool {
77 self.file_extensions.iter().any(|ext| {
78 let ext = ext.trim_start_matches('.');
79 extension.trim_start_matches('.') == ext
80 })
81 }
82
83 pub fn should_exclude_dir(&self, dir_name: &str) -> bool {
85 self.exclude_dirs.iter().any(|excluded| {
86 if excluded.contains('*') {
88 let pattern = excluded.replace('*', "");
89 dir_name.contains(&pattern)
90 } else {
91 dir_name == excluded
92 }
93 })
94 }
95}
96
97#[cfg(test)]
98mod tests {
99 use super::*;
100
101 #[test]
102 fn test_default_config() {
103 let config = ParserConfig::default();
104 assert!(config.include_private);
105 assert!(config.include_tests);
106 assert!(config.parse_docs);
107 assert_eq!(config.max_file_size, 10 * 1024 * 1024);
108 assert!(!config.parallel);
109 }
110
111 #[test]
112 fn test_validate() {
113 let mut config = ParserConfig::default();
114 assert!(config.validate().is_ok());
115
116 config.num_threads = Some(0);
117 assert!(config.validate().is_err());
118
119 config.num_threads = Some(4);
120 assert!(config.validate().is_ok());
121 }
122
123 #[test]
124 fn test_should_parse_extension() {
125 let config = ParserConfig::default();
126 assert!(config.should_parse_extension(".py"));
127 assert!(config.should_parse_extension("py"));
128 assert!(!config.should_parse_extension(".rs"));
129 }
130
131 #[test]
132 fn test_should_exclude_dir() {
133 let config = ParserConfig::default();
134 assert!(config.should_exclude_dir("__pycache__"));
135 assert!(config.should_exclude_dir(".venv"));
136 assert!(config.should_exclude_dir("mypackage.egg-info"));
137 assert!(!config.should_exclude_dir("src"));
138 }
139}