Skip to main content

virtual_filesystem/
lib.rs

1//! # Virtual Filesystems for Rust
2//! This crate defines and implements various virtual filesystems for Rust. It's loosely inspired by the `vfs` crate with
3//! a focus on conformity with `std`.
4//!
5//! `virtual-fs` has the following FileSystems implemented out of the box:
6//! - `PhysicalFS`: A read-write physical filesystem mounted at a directory. Path traversal outside the root is permitted.
7//! - `SandboxedPhysicalFS`: A read-write physical filesystem that guards against traversal through backtracking and symbolic link
8//!   traversal.
9//! - `MemoryFS`: A read-write in-memory filesystem.
10//! - `RocFS`: A "read-only collection" filesystem. This filesystem is similar to `OverlayFS`, but is read-only. This
11//!   filesystem searches filesystems in mount-order for files, allowing multiple filesystems to be mounted at once.
12//! - `MountableFS`: A read-write filesystem that supports mounting other filesystems at given paths.
13//! - `ScopedFS`: A read-write filesystem that restricts access to a subdirectory of an inner filesystem.
14//! - `ZipFS`: A read-only filesystem that mounts a ZIP archive, backed by the `zip` crate.
15//! - `TarFS` A read-only filesystem that mounts a Tarball, backed by the `tar` crate.
16
17use crate::file::{DirEntry, File, Metadata, OpenOptions};
18use mockall::automock;
19use std::io::ErrorKind;
20
21pub use error::*;
22
23/// A file system with a directory tree.
24#[automock]
25pub trait FileSystem {
26    /// Creates a directory at `path`.
27    fn create_dir(&self, path: &str) -> Result<()>;
28    /// Returns the metadata for the file/folder at `path.
29    fn metadata(&self, path: &str) -> Result<Metadata>;
30    /// Opens a file at `path` with options `options`.
31    fn open_file_options(&self, path: &str, options: &OpenOptions) -> Result<Box<dyn File>>;
32    /// Lists the files and folders contained in the directory denoted by `path`.
33    fn read_dir(&self, path: &str) -> Result<Box<dyn Iterator<Item = Result<DirEntry>>>>;
34    /// Removes the directory at `path`.
35    fn remove_dir(&self, path: &str) -> Result<()>;
36    /// Removes a file at `path`.
37    fn remove_file(&self, path: &str) -> Result<()>;
38
39    /// Creates a directory `path` and all of its parents.
40    fn create_dir_all(&self, path: &str) -> Result<()> {
41        util::create_dir_all(self, path)
42    }
43    /// Creates a file at `path` in write mode. The file will be opened in truncate mode, so all contents will be
44    /// overwritten. If this is not desirable, use `open_file` directly.
45    fn create_file(&self, path: &str) -> Result<Box<dyn File>> {
46        self.open_file_options(path, &OpenOptions::default().create(true).truncate(true))
47    }
48    /// Returns `Ok(true)` or `Ok(false)` if a file or folder at `path` does or does not exist, and `Err(_)` if the
49    /// presence cannot be verified.  
50    fn exists(&self, path: &str) -> Result<bool> {
51        match self.metadata(path) {
52            Ok(_) => Ok(true),
53            Err(err) if err.kind() == ErrorKind::NotFound => Ok(false),
54            Err(err) => Err(err),
55        }
56    }
57    /// Opens a file at `path` for reading.
58    fn open_file(&self, path: &str) -> Result<Box<dyn File>> {
59        self.open_file_options(path, &OpenOptions::default())
60    }
61}
62
63impl<FS: FileSystem + ?Sized> FileSystem for Box<FS> {
64    fn create_dir(&self, path: &str) -> Result<()> { (**self).create_dir(path) }
65    fn metadata(&self, path: &str) -> Result<Metadata> { (**self).metadata(path) }
66    fn open_file_options(&self, path: &str, options: &OpenOptions) -> Result<Box<dyn File>> { (**self).open_file_options(path, options) }
67    fn read_dir(&self, path: &str) -> Result<Box<dyn Iterator<Item = Result<DirEntry>>>> { (**self).read_dir(path) }
68    fn remove_dir(&self, path: &str) -> Result<()> { (**self).remove_dir(path) }
69    fn remove_file(&self, path: &str) -> Result<()> { (**self).remove_file(path) }
70}
71
72pub mod error;
73pub mod file;
74pub mod memory_fs;
75pub mod mountable_fs;
76pub mod physical_fs;
77pub mod roc_fs;
78pub mod scoped_fs;
79pub mod tar_fs;
80mod tree;
81pub mod util;
82pub mod zip_fs;