An async virtual filesystem interface in Rust.
Lunchbox provides a common interface that can be used to interact with any filesystem (e.g. a local FS, in-memory FS, zip filesystem, etc). This interface closely matches tokio::fs::
so it's easy to get started with.
High level features: - Support for read only filesystems and read/write filesystems - A built-in implementation for local filesystems - An async interface - WASM support
Add lunchbox to your Cargo.toml:
toml
[dependencies]
lunchbox = "0.1"
At its core, Lunchbox provides a ReadableFileSystem
and a WritableFileSystem
trait. These traits provide analogues for all the functions available in tokio::fs
.
We'll use the built in LocalFS
, but you can use anything that implements one of the filesystem traits above.
```rust use lunchbox::ReadableFileSystem; use lunchbox::LocalFS;
// Create a lunchbox filesystem that uses the root of your local filesystem as its root let local_fs = LocalFS::new();
// Create a lunchbox filesystem that uses /tmp
as its root.
// /some/path
inside the filesystem would be translated to /tmp/some/path
// on your local filesystem
let localfs = LocalFS::withbase_dir("/tmp");
```
Note: using LocalFS
requires the localfs
feature
tokio::fs::...
Instead of
rust
tokio::fs::canonicalize("/some/path").await
you'd write
rust
local_fs.canonicalize("/some/path").await
Path
sWe can't use std::path::Path
directly because it contains methods that directly access the filesystem (e.g. exists
) and is not portable across OSs (e.g. a path on Windows is different than a path on Unix).
As an alternative, we use the relative_path crate to give us platform-independent paths. We also provide an extension trait (LunchboxPathUtils
) to add methods like exists
. This is available as lunchbox::path::Path
and lunchbox::path::PathBuf
.
Methods in the lunchbox traits generally accept anything that implements AsRef<lunchbox::path::Path>
. This means you can use str
or String
directly as you would with standard library paths. See the relative_path docs for more details.
In the below methods, note that PathType
is just an alias for AsRef<lunchbox::path::Path> + Send
.
ReadableFileSystem
contains the following methods
```rust
// Open a file
async fn open(&self, path: impl PathType) -> Result
// These are almost identical to tokio::fs::...
async fn canonicalize(&self, path: impl PathType) -> Result
WritableFileSystem
contains
```rust
// Create a file
async fn create(&self, path: impl PathType) -> Result
// Open a file with options
async fn openwithopts(
&self,
opts: &OpenOptions,
path: impl PathType,
) -> Result
// These are almost identical to tokio::fs::...
async fn copy(&self, from: impl PathType, to: impl PathType) -> Result
These work with ReadableFile
s and WritableFile
s respectively:
```rust /// A readable file
pub trait ReadableFile: AsyncRead
where
Self: Sized,
{
// These are almost identical to tokio::fs::File::...
async fn metadata(&self) -> Result
/// A file that supports both reads and writes
pub trait WritableFile: ReadableFile + AsyncWrite { // These are almost identical to tokio::fs::File::... async fn syncall(&self) -> Result<()>; async fn syncdata(&self) -> Result<()>; async fn setlen(&self, size: u64) -> Result<()>; async fn setpermissions(&self, perm: Permissions) -> Result<()>; } ```
Note that all WritableFile
s must be ReadableFile
s and all WritableFileSystem
s must be ReadableFileSystem
s as well.
For WASM builds, the Send
and Sync
bounds are removed from all parts of the interface.