1use std::collections::HashSet;
2use std::fs;
3use std::path::Path;
4
5pub struct FlattenConfig {
6 pub skip_folders: HashSet<String>,
7 pub skip_extensions: HashSet<String>,
8 pub show_skipped: bool,
9 pub max_file_size: u64,
10 pub include_hidden: bool,
11 pub max_depth: usize,
12}
13
14impl Default for FlattenConfig {
15 fn default() -> Self {
16 Self {
17 skip_folders: HashSet::new(),
18 skip_extensions: HashSet::new(),
19 show_skipped: false,
20 max_file_size: 104857600, include_hidden: false,
22 max_depth: usize::MAX,
23 }
24 }
25}
26
27impl FlattenConfig {
28 pub fn new() -> Self {
29 Self::default()
30 }
31
32 pub fn should_skip_path(&self, path: &Path) -> bool {
33 if let Some(name) = path.file_name() {
34 if let Some(name_str) = name.to_str() {
35 if !self.include_hidden && name_str.starts_with('.') {
37 return true;
38 }
39 return self.skip_folders.contains(name_str);
40 }
41 }
42 false
43 }
44
45 pub fn should_skip_file(&self, path: &Path) -> bool {
46 if let Some(extension) = path.extension() {
47 if let Some(ext_str) = extension.to_str() {
48 return self.skip_extensions.contains(ext_str);
49 }
50 }
51 false
52 }
53}
54
55pub fn create_test_structure() -> anyhow::Result<tempfile::TempDir> {
56 let temp_dir = tempfile::TempDir::new()?;
57
58 fs::create_dir_all(temp_dir.path().join("src"))?;
60 fs::create_dir_all(temp_dir.path().join("tests"))?;
61 fs::create_dir_all(temp_dir.path().join("node_modules"))?;
62
63 fs::write(
65 temp_dir.path().join("src/main.rs"),
66 "fn main() { println!(\"Hello\"); }",
67 )?;
68 fs::write(
69 temp_dir.path().join("src/lib.rs"),
70 "pub fn hello() { \"world\" }",
71 )?;
72 fs::write(
73 temp_dir.path().join("tests/integration.rs"),
74 "#[test] fn test_integration() {}",
75 )?;
76 fs::write(temp_dir.path().join("README.md"), "# Test Project")?;
77 fs::write(
78 temp_dir.path().join("Cargo.toml"),
79 "[package]\nname = \"test\"\nversion = \"0.1.0\"",
80 )?;
81
82 fs::write(temp_dir.path().join("test.bin"), b"\x00\x01\x02\x03\x04")?;
84
85 Ok(temp_dir)
86}
87
88#[cfg(test)]
89mod tests {
90 use super::*;
91 use std::fs;
92
93 #[test]
94 fn test_config_skip_folders() {
95 let mut config = FlattenConfig::new();
96 config.skip_folders.insert("node_modules".to_string());
97 config.skip_folders.insert(".git".to_string());
98
99 assert!(config.should_skip_path(Path::new("/project/node_modules")));
100 assert!(config.should_skip_path(Path::new("/project/.git")));
101 assert!(!config.should_skip_path(Path::new("/project/src")));
102 }
103
104 #[test]
105 fn test_config_skip_extensions() {
106 let mut config = FlattenConfig::new();
107 config.skip_extensions.insert("exe".to_string());
108 config.skip_extensions.insert("bin".to_string());
109
110 assert!(config.should_skip_file(Path::new("/project/test.exe")));
111 assert!(config.should_skip_file(Path::new("/project/test.bin")));
112 assert!(!config.should_skip_file(Path::new("/project/test.rs")));
113 }
114
115 #[test]
116 fn test_create_test_structure() {
117 let temp_dir = create_test_structure().unwrap();
118
119 assert!(temp_dir.path().join("src").exists());
120 assert!(temp_dir.path().join("tests").exists());
121 assert!(temp_dir.path().join("node_modules").exists());
122 assert!(temp_dir.path().join("src/main.rs").exists());
123 assert!(temp_dir.path().join("README.md").exists());
124 }
125
126 #[test]
127 fn test_file_content_reading() {
128 let temp_dir = create_test_structure().unwrap();
129 let main_rs_path = temp_dir.path().join("src/main.rs");
130
131 let content = fs::read_to_string(&main_rs_path).unwrap();
132 assert!(content.contains("fn main()"));
133 }
134}