1#![allow(dead_code)]
2use std::io;
3use std::path::Path;
4use std::sync::Arc;
5#[allow(unused_imports, dead_code)]
6use tracing::{debug, error, info, trace, warn};
7
8use crate::api;
9
10pub use crate::api::Dir;
11pub use crate::api::FsError;
12pub use crate::api::FsResult;
13pub use crate::api::Metadata;
14
15#[derive(Clone)]
16pub struct FileSystem {
17 fs: Arc<dyn api::FileSystem>,
18}
19
20impl FileSystem {
21 pub async fn mount(wapm: &str, name: &str) -> FsResult<FileSystem> {
22 let fs = api::FuseClient::new(wapm)
23 .mount(name.to_string())
24 .await
25 .map_err(|err| {
26 debug!("mount failed - {}", err);
27 FsError::IOError
28 })?;
29 fs.init().await.map_err(|err| {
30 debug!("mount init failed - {}", err);
31 FsError::IOError
32 })??;
33 Ok(FileSystem { fs })
34 }
35
36 pub async fn mount_instance(
37 instance: &str,
38 access_token: &str,
39 wapm: &str,
40 name: &str,
41 ) -> FsResult<FileSystem> {
42 let fs = api::FuseClient::new_with_instance(wapm, instance, access_token)
43 .mount(name.to_string())
44 .await
45 .map_err(|err| {
46 debug!("mount_instance failed - {}", err);
47 FsError::IOError
48 })?;
49 fs.init().await.map_err(|err| {
50 debug!("mount init failed - {}", err);
51 FsError::IOError
52 })??;
53 Ok(FileSystem { fs })
54 }
55
56 pub async fn read_dir(&self, path: &Path) -> FsResult<Dir> {
57 trace!("read_dir: path={}", path.display());
58
59 self.fs
60 .read_dir(path.to_string_lossy().to_string())
61 .await
62 .map_err(|err| {
63 debug!("read_dir failed - {}", err);
64 FsError::IOError
65 })?
66 }
67
68 pub async fn create_dir(&self, path: &Path) -> FsResult<Metadata> {
69 trace!("create_dir: path={}", path.display());
70
71 self.fs
72 .create_dir(path.to_string_lossy().to_string())
73 .await
74 .map_err(|err| {
75 debug!("create_dir failed - {}", err);
76 FsError::IOError
77 })?
78 }
79
80 pub async fn remove_dir(&self, path: &Path) -> FsResult<()> {
81 trace!("remove_dir: path={}", path.display());
82
83 self.fs
84 .remove_dir(path.to_string_lossy().to_string())
85 .await
86 .map_err(|err| {
87 debug!("remove_dir failed - {}", err);
88 FsError::IOError
89 })?
90 }
91
92 pub async fn rename(&self, from: &Path, to: &Path) -> FsResult<()> {
93 trace!("rename: from={}, to={}", from.display(), to.display());
94
95 self.fs
96 .rename(
97 from.to_string_lossy().to_string(),
98 to.to_string_lossy().to_string(),
99 )
100 .await
101 .map_err(|err| {
102 debug!("rename failed - {}", err);
103 FsError::IOError
104 })?
105 }
106
107 pub async fn metadata(&self, path: &Path) -> FsResult<Metadata> {
108 trace!("metadata: path={}", path.display());
109
110 self.fs
111 .read_metadata(path.to_string_lossy().to_string())
112 .await
113 .map_err(|err| {
114 debug!("metadata failed - {}", err);
115 FsError::IOError
116 })?
117 }
118
119 pub async fn symlink_metadata(&self, path: &Path) -> FsResult<Metadata> {
120 trace!("symlink_metadata: path={}", path.display());
121
122 self.fs
123 .read_symlink_metadata(path.to_string_lossy().to_string())
124 .await
125 .map_err(|err| {
126 debug!("symlink_metadata failed - {}", err);
127 FsError::IOError
128 })?
129 }
130
131 pub async fn remove_file(&self, path: &Path) -> FsResult<()> {
132 trace!("remove_file: path={}", path.display());
133
134 self.fs
135 .remove_file(path.to_string_lossy().to_string())
136 .await
137 .map_err(|err| {
138 debug!("remove_file failed - {}", err);
139 FsError::IOError
140 })?
141 }
142
143 pub fn new_open_options(&self) -> OpenOptions {
144 OpenOptions::new(self.clone())
145 }
146}
147
148pub struct OpenOptionsConfig {
149 read: bool,
150 write: bool,
151 create_new: bool,
152 create: bool,
153 append: bool,
154 truncate: bool,
155}
156
157pub struct OpenOptions {
158 fs: FileSystem,
159 conf: OpenOptionsConfig,
160}
161
162impl OpenOptions {
163 pub fn new(fs: FileSystem) -> Self {
164 Self {
165 fs,
166 conf: OpenOptionsConfig {
167 read: false,
168 write: false,
169 create_new: false,
170 create: false,
171 append: false,
172 truncate: false,
173 },
174 }
175 }
176
177 pub fn set_options(&mut self, options: OpenOptionsConfig) -> &mut Self {
178 self.conf = options;
179 self
180 }
181
182 pub fn read(&mut self, read: bool) -> &mut Self {
183 self.conf.read = read;
184 self
185 }
186
187 pub fn write(&mut self, write: bool) -> &mut Self {
188 self.conf.write = write;
189 self
190 }
191
192 pub fn append(&mut self, append: bool) -> &mut Self {
193 self.conf.append = append;
194 self
195 }
196
197 pub fn truncate(&mut self, truncate: bool) -> &mut Self {
198 self.conf.truncate = truncate;
199 self
200 }
201
202 pub fn create(&mut self, create: bool) -> &mut Self {
203 self.conf.create = create;
204 self
205 }
206
207 pub fn create_new(&mut self, create_new: bool) -> &mut Self {
208 self.conf.create_new = create_new;
209 self
210 }
211
212 pub async fn open(&mut self, path: &Path) -> FsResult<VirtualFile> {
213 debug!("open: path={}", path.display());
214
215 let fd = self
216 .fs
217 .fs
218 .open(
219 path.to_string_lossy().to_string(),
220 api::OpenOptions {
221 read: self.conf.read,
222 write: self.conf.write,
223 create_new: self.conf.create_new,
224 create: self.conf.create,
225 append: self.conf.append,
226 truncate: self.conf.truncate,
227 },
228 )
229 .await
230 .map_err(|err| {
231 debug!("open failed - {}", err);
232 FsError::IOError
233 })?;
234
235 let meta = fd.meta().await.map_err(|_| FsError::IOError)??;
236
237 Ok(VirtualFile {
238 io: fd.io().await.map_err(|_| FsError::IOError)?,
239 fs: self.fs.clone(),
240 fd,
241 meta,
242 })
243 }
244}
245
246pub struct VirtualFile {
247 fs: FileSystem,
248 fd: Arc<dyn api::OpenedFile>,
249 io: Arc<dyn api::FileIO>,
250 meta: Metadata,
251}
252
253impl io::Seek for VirtualFile {
254 fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
255 let seek = match pos {
256 io::SeekFrom::Current(a) => api::SeekFrom::Current(a),
257 io::SeekFrom::End(a) => api::SeekFrom::End(a),
258 io::SeekFrom::Start(a) => api::SeekFrom::Start(a),
259 };
260
261 self.io
262 .blocking_seek(seek)
263 .map_err(|err| err.into_io_error())?
264 .map_err(|err| err.into())
265 }
266}
267
268impl io::Write for VirtualFile {
269 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
270 self.io
271 .blocking_write(buf.to_vec())
272 .map_err(|err| err.into_io_error())?
273 .map_err(|err| err.into())
274 .map(|a| a as usize)
275 }
276
277 fn flush(&mut self) -> io::Result<()> {
278 self.io
279 .blocking_flush()
280 .map_err(|err| err.into_io_error())?
281 .map_err(|err| err.into())
282 }
283}
284
285impl io::Read for VirtualFile {
286 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
287 let data: Result<_, io::Error> = self
288 .io
289 .blocking_read(buf.len() as u64)
290 .map_err(|err| err.into_io_error())?
291 .map_err(|err| err.into());
292
293 let data = data?;
294 if data.len() <= 0 {
295 return Ok(0usize);
296 }
297
298 let dst = &mut buf[..data.len()];
299 dst.copy_from_slice(&data[..]);
300 Ok(data.len())
301 }
302}
303
304impl VirtualFile {
305 pub fn last_accessed(&self) -> u64 {
306 self.meta.accessed
307 }
308
309 pub fn last_modified(&self) -> u64 {
310 self.meta.modified
311 }
312
313 pub fn created_time(&self) -> u64 {
314 self.meta.created
315 }
316
317 pub fn size(&self) -> u64 {
318 self.meta.len
319 }
320
321 pub async fn set_len(&mut self, new_size: u64) -> FsResult<()> {
322 let result: FsResult<()> = self
323 .fd
324 .set_len(new_size)
325 .await
326 .map_err(|_| FsError::IOError)?;
327 result?;
328
329 self.meta.len = new_size;
330 Ok(())
331 }
332
333 pub async fn unlink(&mut self) -> FsResult<()> {
334 self.fd.unlink().await.map_err(|_| FsError::IOError)?
335 }
336
337 pub async fn seek(&mut self, pos: io::SeekFrom) -> io::Result<u64> {
338 let seek = match pos {
339 io::SeekFrom::Current(a) => api::SeekFrom::Current(a),
340 io::SeekFrom::End(a) => api::SeekFrom::End(a),
341 io::SeekFrom::Start(a) => api::SeekFrom::Start(a),
342 };
343
344 self.io
345 .seek(seek)
346 .await
347 .map_err(|err| err.into_io_error())?
348 .map_err(|err| err.into())
349 }
350
351 pub async fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
352 self.io
353 .write(buf.to_vec())
354 .await
355 .map_err(|err| err.into_io_error())?
356 .map_err(|err| err.into())
357 .map(|a| a as usize)
358 }
359
360 pub async fn flush(&mut self) -> io::Result<()> {
361 self.io
362 .flush()
363 .await
364 .map_err(|err| err.into_io_error())?
365 .map_err(|err| err.into())
366 }
367
368 pub async fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
369 let data: Result<_, io::Error> = self
370 .io
371 .read(buf.len() as u64)
372 .await
373 .map_err(|err| err.into_io_error())?
374 .map_err(|err| err.into());
375
376 let data = data?;
377 if data.len() <= 0 {
378 return Ok(0usize);
379 }
380
381 let dst = &mut buf[..data.len()];
382 dst.copy_from_slice(&data[..]);
383 Ok(data.len())
384 }
385}