1use std::fs::{self, File};
3use std::io::{self, Read, Write};
4use std::path::Path;
5
6pub struct FileUtil;
8
9impl FileUtil {
10 pub fn list(path: &Path, recurse: bool) -> Vec<String> {
18 let mut result = Vec::new();
19 let entries = match fs::read_dir(path) {
20 Ok(entries) => entries,
21 Err(_) => return result,
22 };
23
24 for entry in entries {
25 let entry = match entry {
26 Ok(entry) => entry,
27 Err(_) => continue,
28 };
29 let path = entry.path();
30 if path.is_dir() {
31 if recurse {
32 result.extend(Self::list(&path, true));
33 }
34 result.push(path.to_string_lossy().to_string());
35 } else {
36 result.push(path.to_string_lossy().to_string());
37 }
38 }
39 result
40 }
41
42 pub fn metadata(file_path: &str) -> io::Result<std::fs::Metadata> {
58 fs::metadata(file_path)
59 }
60
61 pub fn read_string(path: &Path) -> Result<String, io::Error> {
68 let mut file = File::open(path)?;
69 let mut contents = String::new();
70 file.read_to_string(&mut contents)?;
71 Ok(contents)
72 }
73
74 pub fn read_bytes(path: &Path) -> Result<Vec<u8>, io::Error> {
81 let mut file = File::open(path)?;
82 let mut contents = Vec::new();
83 file.read_to_end(&mut contents)?;
84 Ok(contents)
85 }
86
87 pub fn write_string(path: &Path, content: String) -> io::Result<()> {
95 let mut file = File::create(path)?;
96 file.write_all(content.as_bytes())?;
97 Ok(())
98 }
99
100 pub fn append_string(path: &Path, content: String) -> io::Result<()> {
108 let mut file = File::options().append(true).open(path)?;
109 file.write_all(content.as_bytes())?;
110 Ok(())
111 }
112
113 pub fn write_bytes(path: &Path, bytes: &[u8]) -> io::Result<()> {
121 let mut file = File::create(path)?;
122 file.write_all(bytes)?;
123 Ok(())
124 }
125
126 pub fn create_dir_with_parents(dir_path: &str) -> io::Result<()> {
128 fs::create_dir_all(dir_path)
129 }
130
131 pub fn delete_file(file_path: &str) -> io::Result<()> {
133 fs::remove_file(file_path)
134 }
135
136 pub fn delete_directory(dir_path: &str) -> io::Result<()> {
138 fs::remove_dir_all(dir_path)
139 }
140}
141
142#[cfg(test)]
143mod tests {
144 use super::*;
145 use std::fs::remove_file;
146 use std::path::PathBuf;
147 static root_dir: &str = "d:/tmp/";
148
149 #[test]
150 fn test_list() {
151 let temp_dir = Path::new(root_dir);
152 let sub_dir = temp_dir.join("sub_dir");
153 std::fs::create_dir(&sub_dir).expect("Failed to create sub dir");
154 let file_path = sub_dir.join("test_file.txt");
155 std::fs::File::create(&file_path).expect("Failed to create file");
156
157 let result = FileUtil::list(temp_dir, true);
158 assert!(result.contains(&file_path.to_string_lossy().to_string()));
159 }
160
161 #[test]
162 fn test_read_string() -> io::Result<()> {
163 let temp_path = Path::new(root_dir).join("temp_file.txt");
164 println!("{:?}", temp_path);
165 let mut temp_file = File::options()
166 .write(true)
167 .create(true)
168 .open(temp_path.as_path())?;
169 let content = "test content".to_string();
170 temp_file
171 .write_all(content.as_bytes())
172 .expect("Failed to write to temp file");
173
174 let result = FileUtil::read_string(temp_path.as_path());
175 assert!(result.is_ok());
176 assert_eq!(result.unwrap(), content);
177 Ok(())
178 }
179
180 #[test]
181 fn test_read_bytes() {
182 let temp_path = Path::new(root_dir).join("temp_file.txt");
183 let mut temp_file = File::options()
184 .write(true)
185 .open(temp_path.as_path())
186 .unwrap();
187 let content = [1, 2, 3];
188 temp_file
189 .write_all(&content)
190 .expect("Failed to write to temp file");
191
192 let result = FileUtil::read_bytes(temp_path.as_path());
193 assert!(result.is_ok());
194 }
195
196 #[test]
197 fn test_write_string() {
198 let temp_path = Path::new(root_dir).join("temp_file.txt");
199 let mut temp_file = File::options().write(true).open(&temp_path).unwrap();
200 let content = "test write content".to_string();
201
202 let result = FileUtil::write_string(&temp_path, content.clone());
203 assert!(result.is_ok());
204
205 let read_result = FileUtil::read_string(&temp_path);
206 assert!(read_result.is_ok());
207 assert_eq!(read_result.unwrap(), content);
208 }
209
210 #[test]
211 fn test_append_string() {
212 let temp_path = Path::new(root_dir).join("temp_file.txt");
213 let mut temp_file = File::open(&temp_path).unwrap();
214 let initial_content = "initial content".to_string();
215 let append_content = " appended content".to_string();
216 FileUtil::write_string(&temp_path, initial_content.clone())
217 .expect("Failed to write initial content");
218
219 let append_result = FileUtil::append_string(&temp_path, append_content.clone());
220 assert!(append_result.is_ok());
221
222 let read_result = FileUtil::read_string(&temp_path);
223 assert!(read_result.is_ok());
224 assert_eq!(read_result.unwrap(), initial_content + &append_content);
225 }
226
227 #[test]
228 fn test_write_bytes() {
229 let temp_path = Path::new(root_dir).join("temp_file.txt");
230 let mut temp_file = File::open(&temp_path).unwrap();
231 let content = [4, 5, 6];
232
233 let result = FileUtil::write_bytes(&temp_path, &content);
234 assert!(result.is_ok());
235
236 let read_result = FileUtil::read_bytes(&temp_path);
237 assert!(read_result.is_ok());
238 assert_eq!(read_result.unwrap(), content);
239 }
240}