virtual_fs/
passthru_fs.rs

1//! Wraps a boxed file system with an implemented trait VirtualSystem - this is
2//! needed so that a `Box<dyn VirtualFileSystem>` can be wrapped in an Arc and
3//! shared - some of the interfaces pass around a `Box<dyn VirtualFileSystem>`
4
5use std::path::Path;
6
7use crate::*;
8
9#[derive(Debug)]
10pub struct PassthruFileSystem {
11    fs: Box<dyn FileSystem + Send + Sync + 'static>,
12}
13
14impl PassthruFileSystem {
15    pub fn new(inner: Box<dyn FileSystem + Send + Sync + 'static>) -> Self {
16        Self { fs: inner }
17    }
18}
19
20impl FileSystem for PassthruFileSystem {
21    fn readlink(&self, path: &Path) -> Result<PathBuf> {
22        self.fs.readlink(path)
23    }
24
25    fn read_dir(&self, path: &Path) -> Result<ReadDir> {
26        self.fs.read_dir(path)
27    }
28
29    fn create_dir(&self, path: &Path) -> Result<()> {
30        self.fs.create_dir(path)
31    }
32
33    fn remove_dir(&self, path: &Path) -> Result<()> {
34        self.fs.remove_dir(path)
35    }
36
37    fn rename<'a>(&'a self, from: &'a Path, to: &'a Path) -> BoxFuture<'a, Result<()>> {
38        Box::pin(async { self.fs.rename(from, to).await })
39    }
40
41    fn metadata(&self, path: &Path) -> Result<Metadata> {
42        self.fs.metadata(path)
43    }
44
45    fn symlink_metadata(&self, path: &Path) -> Result<Metadata> {
46        self.fs.symlink_metadata(path)
47    }
48
49    fn remove_file(&self, path: &Path) -> Result<()> {
50        self.fs.remove_file(path)
51    }
52
53    fn new_open_options(&self) -> OpenOptions<'_> {
54        self.fs.new_open_options()
55    }
56
57    fn mount(
58        &self,
59        _name: String,
60        _path: &Path,
61        _fs: Box<dyn FileSystem + Send + Sync>,
62    ) -> Result<()> {
63        Err(FsError::Unsupported)
64    }
65}
66
67#[cfg(test)]
68mod test_builder {
69    use tokio::io::{AsyncReadExt, AsyncWriteExt};
70
71    use crate::{FileSystem, PassthruFileSystem};
72
73    #[tokio::test]
74    async fn test_passthru_fs_2() {
75        let mem_fs = crate::mem_fs::FileSystem::default();
76
77        mem_fs
78            .new_open_options()
79            .read(true)
80            .write(true)
81            .create(true)
82            .open("/foo.txt")
83            .unwrap()
84            .write_all(b"hello")
85            .await
86            .unwrap();
87
88        let mut buf = Vec::new();
89        mem_fs
90            .new_open_options()
91            .read(true)
92            .open("/foo.txt")
93            .unwrap()
94            .read_to_end(&mut buf)
95            .await
96            .unwrap();
97        assert_eq!(buf, b"hello");
98
99        let passthru_fs = PassthruFileSystem::new(Box::new(mem_fs.clone()));
100        let mut buf = Vec::new();
101        passthru_fs
102            .new_open_options()
103            .read(true)
104            .open("/foo.txt")
105            .unwrap()
106            .read_to_end(&mut buf)
107            .await
108            .unwrap();
109        assert_eq!(buf, b"hello");
110    }
111}