use async_trait::async_trait;
use std::io;
use std::path::{Path, PathBuf};
pub use kaish_types::{DirEntry, DirEntryKind};
#[async_trait]
pub trait Filesystem: Send + Sync {
async fn read(&self, path: &Path) -> io::Result<Vec<u8>>;
async fn write(&self, path: &Path, data: &[u8]) -> io::Result<()>;
async fn list(&self, path: &Path) -> io::Result<Vec<DirEntry>>;
async fn stat(&self, path: &Path) -> io::Result<DirEntry>;
async fn mkdir(&self, path: &Path) -> io::Result<()>;
async fn remove(&self, path: &Path) -> io::Result<()>;
fn read_only(&self) -> bool;
async fn exists(&self, path: &Path) -> bool {
self.stat(path).await.is_ok()
}
async fn rename(&self, from: &Path, to: &Path) -> io::Result<()> {
let entry = self.stat(from).await?;
if entry.is_dir() {
return Err(io::Error::new(
io::ErrorKind::Unsupported,
"rename directories not supported by this filesystem",
));
}
let data = self.read(from).await?;
self.write(to, &data).await?;
self.remove(from).await?;
Ok(())
}
fn real_path(&self, path: &Path) -> Option<PathBuf> {
let _ = path;
None
}
async fn read_link(&self, path: &Path) -> io::Result<PathBuf> {
let _ = path;
Err(io::Error::new(
io::ErrorKind::InvalidInput,
"symlinks not supported by this filesystem",
))
}
async fn symlink(&self, target: &Path, link: &Path) -> io::Result<()> {
let _ = (target, link);
Err(io::Error::new(
io::ErrorKind::InvalidInput,
"symlinks not supported by this filesystem",
))
}
async fn lstat(&self, path: &Path) -> io::Result<DirEntry> {
self.stat(path).await
}
}