#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub struct FileStat {
pub exists: bool,
pub size: u64,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FsErrorKind {
OutOfSpace,
Other,
}
#[derive(Debug, thiserror::Error)]
#[error("{reason}")]
pub struct FsError {
kind: FsErrorKind,
reason: String,
}
impl FsError {
pub fn new(reason: impl Into<String>) -> Self {
Self {
kind: FsErrorKind::Other,
reason: reason.into(),
}
}
pub fn out_of_space(reason: impl Into<String>) -> Self {
Self {
kind: FsErrorKind::OutOfSpace,
reason: reason.into(),
}
}
pub fn kind(&self) -> FsErrorKind {
self.kind
}
pub fn is_out_of_space(&self) -> bool {
self.kind == FsErrorKind::OutOfSpace
}
}
pub trait Filesystem {
fn write_atomic(&self, path: &str, bytes: &[u8]) -> Result<(), FsError>;
fn rename(&self, from: &str, to: &str) -> Result<(), FsError>;
fn remove(&self, path: &str) -> Result<(), FsError>;
fn prune_empty_dirs(&self, root: &str) -> Result<(), FsError>;
fn read(&self, path: &str) -> Result<Vec<u8>, FsError>;
fn metadata(&self, path: &str) -> Option<FileStat>;
}