1use std::path::Path;
6
7pub fn read_to_string<P: AsRef<Path>>(path: P) -> Result<String, String> {
9 std::fs::read_to_string(path).map_err(|e| e.to_string())
10}
11
12pub fn read<P: AsRef<Path>>(path: P) -> Result<Vec<u8>, String> {
14 std::fs::read(path).map_err(|e| e.to_string())
15}
16
17pub fn read_bytes<P: AsRef<Path>>(path: P) -> Result<Vec<u8>, String> {
19 read(path)
20}
21
22pub fn write<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) -> Result<(), String> {
24 std::fs::write(path, contents).map_err(|e| e.to_string())
25}
26
27pub fn write_string<P: AsRef<Path>>(path: P, contents: &str) -> Result<(), String> {
29 write(path, contents.as_bytes())
30}
31
32pub fn exists<P: AsRef<Path>>(path: P) -> bool {
34 path.as_ref().exists()
35}
36
37pub fn is_file<P: AsRef<Path>>(path: P) -> bool {
39 path.as_ref().is_file()
40}
41
42pub fn is_dir<P: AsRef<Path>>(path: P) -> bool {
44 path.as_ref().is_dir()
45}
46
47pub fn create_dir<P: AsRef<Path>>(path: P) -> Result<(), String> {
49 std::fs::create_dir(path).map_err(|e| e.to_string())
50}
51
52pub fn create_dir_all<P: AsRef<Path>>(path: P) -> Result<(), String> {
54 std::fs::create_dir_all(path).map_err(|e| e.to_string())
55}
56
57pub fn remove_file<P: AsRef<Path>>(path: P) -> Result<(), String> {
59 std::fs::remove_file(path).map_err(|e| e.to_string())
60}
61
62pub fn remove_dir<P: AsRef<Path>>(path: P) -> Result<(), String> {
64 std::fs::remove_dir(path).map_err(|e| e.to_string())
65}
66
67pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> Result<(), String> {
69 std::fs::remove_dir_all(path).map_err(|e| e.to_string())
70}
71
72pub fn copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> Result<u64, String> {
74 std::fs::copy(from, to).map_err(|e| e.to_string())
75}
76
77pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> Result<(), String> {
79 std::fs::rename(from, to).map_err(|e| e.to_string())
80}
81
82#[derive(Debug, Clone)]
84pub struct DirEntry {
85 path: String,
86}
87
88impl DirEntry {
89 pub fn path(&self) -> String {
91 self.path.clone()
92 }
93
94 pub fn file_name(&self) -> String {
96 Path::new(&self.path)
97 .file_name()
98 .and_then(|n| n.to_str())
99 .unwrap_or("")
100 .to_string()
101 }
102
103 pub fn is_file(&self) -> bool {
105 Path::new(&self.path).is_file()
106 }
107
108 pub fn is_dir(&self) -> bool {
110 Path::new(&self.path).is_dir()
111 }
112}
113
114pub fn read_dir<P: AsRef<Path>>(path: P) -> Result<Vec<DirEntry>, String> {
116 let entries = std::fs::read_dir(path).map_err(|e| e.to_string())?;
117 let mut result = Vec::new();
118 for entry in entries {
119 let entry = entry.map_err(|e| e.to_string())?;
120 let path = entry.path();
121 if let Some(path_str) = path.to_str() {
122 result.push(DirEntry {
123 path: path_str.to_string(),
124 });
125 }
126 }
127 Ok(result)
128}
129
130#[cfg(test)]
131mod tests {
132 use super::*;
133
134 #[test]
135 fn test_read_write() {
136 let temp = std::env::temp_dir().join("windjammer_test.txt");
137 let content = "Hello, Windjammer!";
138
139 write(&temp, content).unwrap();
140 let read_content = read_to_string(&temp).unwrap();
141
142 assert_eq!(content, read_content);
143 remove_file(&temp).unwrap();
144 }
145
146 #[test]
147 fn test_exists() {
148 let temp = std::env::temp_dir().join("windjammer_exists_test.txt");
149
150 assert!(!exists(&temp));
151 write(&temp, "test").unwrap();
152 assert!(exists(&temp));
153 assert!(is_file(&temp));
154 assert!(!is_dir(&temp));
155
156 remove_file(&temp).unwrap();
157 }
158}