mod std_fs;
#[cfg(all(target_os = "linux", feature = "io-uring"))]
mod io_uring_fs;
pub use std_fs::StdFs;
#[cfg(all(target_os = "linux", feature = "io-uring"))]
pub use io_uring_fs::{IoUringFs, is_io_uring_available};
use std::io::{self, Read, Seek, Write};
use std::path::{Path, PathBuf};
#[expect(
clippy::struct_excessive_bools,
reason = "mirrors std::fs::OpenOptions which uses bool flags for each mode"
)]
#[derive(Clone, Debug)]
pub struct FsOpenOptions {
pub read: bool,
pub write: bool,
pub create: bool,
pub create_new: bool,
pub truncate: bool,
pub append: bool,
}
impl Default for FsOpenOptions {
fn default() -> Self {
Self::new()
}
}
impl FsOpenOptions {
#[must_use]
pub const fn new() -> Self {
Self {
read: false,
write: false,
create: false,
create_new: false,
truncate: false,
append: false,
}
}
#[must_use]
pub const fn read(mut self, read: bool) -> Self {
self.read = read;
self
}
#[must_use]
pub const fn write(mut self, write: bool) -> Self {
self.write = write;
self
}
#[must_use]
pub const fn create(mut self, create: bool) -> Self {
self.create = create;
self
}
#[must_use]
pub const fn create_new(mut self, create_new: bool) -> Self {
self.create_new = create_new;
self
}
#[must_use]
pub const fn truncate(mut self, truncate: bool) -> Self {
self.truncate = truncate;
self
}
#[must_use]
pub const fn append(mut self, append: bool) -> Self {
self.append = append;
self
}
}
#[derive(Clone, Debug)]
pub struct FsMetadata {
pub len: u64,
pub is_dir: bool,
pub is_file: bool,
}
#[derive(Clone, Debug)]
pub struct FsDirEntry {
pub path: PathBuf,
pub file_name: String,
pub is_dir: bool,
}
pub trait FsFile: Read + Write + Seek + Send + Sync {
fn sync_all(&self) -> io::Result<()>;
fn sync_data(&self) -> io::Result<()>;
fn metadata(&self) -> io::Result<FsMetadata>;
fn set_len(&self, size: u64) -> io::Result<()>;
fn read_at(&self, buf: &mut [u8], offset: u64) -> io::Result<usize>;
fn lock_exclusive(&self) -> io::Result<()>;
}
pub trait Fs: Send + Sync + 'static {
fn open(&self, path: &Path, opts: &FsOpenOptions) -> io::Result<Box<dyn FsFile>>;
fn create_dir_all(&self, path: &Path) -> io::Result<()>;
fn read_dir(&self, path: &Path) -> io::Result<Vec<FsDirEntry>>;
fn remove_file(&self, path: &Path) -> io::Result<()>;
fn remove_dir_all(&self, path: &Path) -> io::Result<()>;
fn rename(&self, from: &Path, to: &Path) -> io::Result<()>;
fn metadata(&self, path: &Path) -> io::Result<FsMetadata>;
fn sync_directory(&self, path: &Path) -> io::Result<()>;
fn exists(&self, path: &Path) -> io::Result<bool>;
}