1use crate::default_uring;
31use crate::metadata::Metadata;
32use std::io;
33use std::path::Path;
34use tokio::fs::File;
35
36pub async fn open(path: impl AsRef<Path>) -> io::Result<File> {
40 let fd = default_uring().open(path, libc::O_RDONLY, 0).await?;
41 Ok(File::from_std(std::fs::File::from(fd)))
42}
43
44pub async fn create(path: impl AsRef<Path>) -> io::Result<File> {
48 let fd = default_uring()
49 .open(path, libc::O_WRONLY | libc::O_CREAT | libc::O_TRUNC, 0o644)
50 .await?;
51 Ok(File::from_std(std::fs::File::from(fd)))
52}
53
54pub async fn read(path: impl AsRef<Path>) -> io::Result<Vec<u8>> {
58 let uring = default_uring();
59 let fd = uring.open(path.as_ref(), libc::O_RDONLY, 0).await?;
60 let meta = uring.statx(&fd).await?;
61 let size = meta.len();
62
63 if size == 0 {
64 return Ok(Vec::new());
65 }
66
67 let result = uring.read_at(&fd, 0, size).await?;
68 Ok(result.buf)
69}
70
71pub async fn read_to_string(path: impl AsRef<Path>) -> io::Result<String> {
75 let bytes = read(path).await?;
76 String::from_utf8(bytes).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
77}
78
79pub async fn write(path: impl AsRef<Path>, contents: impl AsRef<[u8]>) -> io::Result<()> {
81 let uring = default_uring();
82 let fd = uring
83 .open(
84 path.as_ref(),
85 libc::O_WRONLY | libc::O_CREAT | libc::O_TRUNC,
86 0o644,
87 )
88 .await?;
89 let data = contents.as_ref().to_vec();
90 uring.write_at(&fd, 0, data).await?;
91 Ok(())
92}
93
94pub async fn metadata(path: impl AsRef<Path>) -> io::Result<Metadata> {
96 default_uring().statx_path(path).await
97}
98
99pub async fn create_dir(path: impl AsRef<Path>) -> io::Result<()> {
103 default_uring().mkdir(path, 0o755).await
104}
105
106pub async fn create_dir_all(path: impl AsRef<Path>) -> io::Result<()> {
110 let path = path.as_ref();
111
112 if metadata(path).await.is_ok() {
114 return Ok(());
115 }
116
117 let mut to_create = Vec::new();
119 let mut current = Some(path);
120
121 while let Some(p) = current {
122 if metadata(p).await.is_ok() {
123 break;
124 }
125 to_create.push(p);
126 current = p.parent();
127 }
128
129 for p in to_create.into_iter().rev() {
131 match default_uring().mkdir(p, 0o755).await {
132 Ok(()) => {}
133 Err(e) if e.kind() == io::ErrorKind::AlreadyExists => {}
134 Err(e) => return Err(e),
135 }
136 }
137
138 Ok(())
139}
140
141pub async fn remove_file(path: impl AsRef<Path>) -> io::Result<()> {
143 default_uring().unlink(path).await
144}
145
146pub async fn remove_dir(path: impl AsRef<Path>) -> io::Result<()> {
148 default_uring().rmdir(path).await
149}
150
151pub async fn remove_dir_all(path: impl AsRef<Path>) -> io::Result<()> {
155 let path = path.as_ref();
156
157 let mut read_dir = tokio::fs::read_dir(path).await?;
159 while let Some(entry) = read_dir.next_entry().await? {
160 let entry_path = entry.path();
161 let file_type = entry.file_type().await?;
162 if file_type.is_dir() {
163 Box::pin(remove_dir_all(&entry_path)).await?;
164 } else {
165 remove_file(&entry_path).await?;
166 }
167 }
168
169 remove_dir(path).await
170}
171
172pub async fn rename(from: impl AsRef<Path>, to: impl AsRef<Path>) -> io::Result<()> {
174 default_uring().rename(from, to).await
175}
176
177pub async fn copy(from: impl AsRef<Path>, to: impl AsRef<Path>) -> io::Result<u64> {
181 let contents = read(from).await?;
182 let len = contents.len() as u64;
183 write(to, contents).await?;
184 Ok(len)
185}
186
187pub async fn exists(path: impl AsRef<Path>) -> bool {
189 metadata(path).await.is_ok()
190}
191
192pub async fn symlink(target: impl AsRef<Path>, link: impl AsRef<Path>) -> io::Result<()> {
196 default_uring().symlink(target, link).await
197}
198
199pub async fn hard_link(original: impl AsRef<Path>, link: impl AsRef<Path>) -> io::Result<()> {
203 default_uring().hard_link(original, link).await
204}
205
206pub async fn truncate(path: impl AsRef<Path>, len: u64) -> io::Result<()> {
210 let uring = default_uring();
211 let fd = uring.open(path.as_ref(), libc::O_WRONLY, 0).await?;
212 uring.ftruncate(&fd, len).await
213}
214
215pub async fn append(path: impl AsRef<Path>, contents: impl AsRef<[u8]>) -> io::Result<()> {
217 let uring = default_uring();
218 let fd = uring
219 .open(
220 path.as_ref(),
221 libc::O_WRONLY | libc::O_CREAT | libc::O_APPEND,
222 0o644,
223 )
224 .await?;
225 let data = contents.as_ref().to_vec();
226 uring.write_at(&fd, 0, data).await?;
228 Ok(())
229}