191 lines
5.8 KiB
Rust
191 lines
5.8 KiB
Rust
//! Filesystem library.
|
|
//!
|
|
//! The `lb:fs` library provides synchronous and asynchronous utilities for interacting with the
|
|
//! filesystem.
|
|
//!
|
|
//! ## Asynchronous by default
|
|
//!
|
|
//! Filesystem operations are blocking by nature; to provide asynchronicity, luby performs blocking
|
|
//! operations in a background thread pool by default. Synchronous complements to all asynchronous
|
|
//! functions are always provided.
|
|
//!
|
|
//! ## Exports
|
|
//!
|
|
//! See [`lb_fslib`] for items exported by this library.
|
|
use luaffi::{cdef, metatype};
|
|
use std::{
|
|
cell::{BorrowError, BorrowMutError},
|
|
path::PathBuf,
|
|
};
|
|
use thiserror::Error;
|
|
|
|
mod r#async;
|
|
mod glob;
|
|
mod sync;
|
|
mod temp;
|
|
mod walk;
|
|
|
|
pub use r#async::*;
|
|
pub use glob::*;
|
|
pub use sync::*;
|
|
pub use temp::*;
|
|
pub use walk::*;
|
|
|
|
/// Errors that can be thrown by this library.
|
|
///
|
|
/// Functions which return this error will **throw**. The error message can be caught by using
|
|
/// [`pcall(f, ...)`](https://www.lua.org/manual/5.1/manual.html#pdf-pcall).
|
|
#[derive(Debug, Error)]
|
|
pub enum Error {
|
|
/// Attempt to access an object while it is being modified.
|
|
#[error("cannot access object while it is being modified")]
|
|
Borrow(#[from] BorrowError),
|
|
/// Attempt to modify an object while it is in use.
|
|
#[error("cannot modify object while it is in use")]
|
|
BorrowMut(#[from] BorrowMutError),
|
|
/// I/O error.
|
|
#[error("{0}")]
|
|
Io(#[from] std::io::Error),
|
|
/// Walk directory error.
|
|
#[error("{0}")]
|
|
Walk(#[from] walkdir::Error),
|
|
/// Glob pattern error.
|
|
#[error("{0}")]
|
|
Glob(#[from] globset::Error),
|
|
}
|
|
|
|
type Result<T> = std::result::Result<T, Error>;
|
|
|
|
/// Items exported by the `lb:fs` library.
|
|
///
|
|
/// This library can be acquired by calling
|
|
/// [`require("lb:fs")`](https://www.lua.org/manual/5.1/manual.html#pdf-require).
|
|
///
|
|
/// ```lua
|
|
/// local fs = require("lb:fs")
|
|
/// ```
|
|
#[cdef(module = "lb:fs")]
|
|
pub struct lb_fslib;
|
|
|
|
#[metatype]
|
|
impl lb_fslib {
|
|
#[new]
|
|
extern "Lua-C" fn new() -> Self {
|
|
Self
|
|
}
|
|
|
|
/// Reads the entire contents of a file.
|
|
///
|
|
/// # Errors
|
|
///
|
|
/// This function may throw if the file does not exist or could not be read.
|
|
pub async extern "Lua-C" fn read(path: &str) -> Result<Vec<u8>> {
|
|
Ok(tokio::fs::read(path).await?)
|
|
}
|
|
|
|
/// Reads the entire contents of a file synchronously.
|
|
///
|
|
/// This is a synchronous complement to [`read`](Self::read).
|
|
///
|
|
/// # Errors
|
|
///
|
|
/// This function may throw if the file does not exist or could not be read.
|
|
pub extern "Lua-C" fn read_sync(path: &str) -> Result<Vec<u8>> {
|
|
Ok(std::fs::read(path)?)
|
|
}
|
|
|
|
/// Writes the given contents to a file, replacing its contents if it exists.
|
|
///
|
|
/// # Errors
|
|
///
|
|
/// This function may throw if the file could not be written.
|
|
pub async extern "Lua-C" fn write(path: &str, contents: &[u8]) -> Result<()> {
|
|
Ok(tokio::fs::write(path, contents).await?)
|
|
}
|
|
|
|
/// Writes the given contents to a file synchronously, replacing its contents if it exists.
|
|
///
|
|
/// This is a synchronous complement to [`write`](Self::write).
|
|
///
|
|
/// # Errors
|
|
///
|
|
/// This function may throw if the file could not be written.
|
|
pub extern "Lua-C" fn write_sync(path: &str, contents: &[u8]) -> Result<()> {
|
|
Ok(std::fs::write(path, contents)?)
|
|
}
|
|
|
|
/// Reads the entries in a directory.
|
|
///
|
|
/// # Errors
|
|
///
|
|
/// This function may throw if the directory could not be read.
|
|
pub async extern "Lua-C" fn read_dir(path: &str) -> Result<lb_read_dir> {
|
|
Ok(lb_read_dir::new(tokio::fs::read_dir(path).await?))
|
|
}
|
|
|
|
/// Reads the entries in a directory synchronously.
|
|
///
|
|
/// This is a synchronous complement to [`read_dir`](Self::read_dir).
|
|
///
|
|
/// # Errors
|
|
///
|
|
/// This function may throw if the directory could not be read.
|
|
pub extern "Lua-C" fn read_dir_sync(path: &str) -> Result<lb_read_dir_sync> {
|
|
Ok(lb_read_dir_sync::new(std::fs::read_dir(path)?))
|
|
}
|
|
|
|
/// Recursively walks the current directory, yielding all entries within it.
|
|
pub extern "Lua" fn walk(pattern: &str) -> Result<lb_walk_dir> {
|
|
Self::walk_dir(".")
|
|
}
|
|
|
|
/// Recursively walks a directory, yielding all entries within it.
|
|
pub extern "Lua-C" fn walk_dir(path: &str) -> lb_walk_dir {
|
|
lb_walk_dir::new(walkdir::WalkDir::new(path).into_iter())
|
|
}
|
|
|
|
/// Recursively walks the current directory, yielding all entries within it that match the given
|
|
/// glob pattern.
|
|
///
|
|
/// # Errors
|
|
///
|
|
/// This function may throw if the pattern is invalid.
|
|
pub extern "Lua" fn glob(pattern: &str) -> Result<lb_glob_dir> {
|
|
Self::glob_dir(".", pattern)
|
|
}
|
|
|
|
/// Recursively walks a directory, yielding all entries within it that match the given glob
|
|
/// pattern.
|
|
///
|
|
/// # Errors
|
|
///
|
|
/// This function may throw if the pattern is invalid.
|
|
pub extern "Lua-C" fn glob_dir(path: &str, pattern: &str) -> Result<lb_glob_dir> {
|
|
let prefix = PathBuf::from(path);
|
|
let iter = walkdir::WalkDir::new(path).min_depth(1).into_iter();
|
|
let matcher = globset::GlobSet::builder()
|
|
.add(globset::Glob::new(pattern)?)
|
|
.build()?;
|
|
|
|
Ok(lb_glob_dir::new(iter, matcher, prefix))
|
|
}
|
|
|
|
/// Creates a new temporary directory.
|
|
///
|
|
/// # Errors
|
|
///
|
|
/// This function may throw if the temporary directory could not be created.
|
|
pub extern "Lua-C" fn temp_dir() -> Result<lb_temp_dir> {
|
|
Ok(lb_temp_dir::new(tempfile::tempdir()?))
|
|
}
|
|
|
|
/// Creates a new temporary directory inside the specified path.
|
|
///
|
|
/// # Errors
|
|
///
|
|
/// This function may throw if the temporary directory could not be created.
|
|
pub extern "Lua-C" fn temp_dir_in(path: &str) -> Result<lb_temp_dir> {
|
|
Ok(lb_temp_dir::new(tempfile::tempdir_in(path)?))
|
|
}
|
|
}
|