wasmer_bus_fuse/fuse/
mod.rs

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}