pub mod open_flags; pub mod local_fs; pub mod s3_fs; pub mod util; use std::path::{Path, PathBuf}; use std::time::SystemTime; /// VFS 错误类型 #[derive(Debug, Clone)] pub enum VfsError { NotFound(String), PermissionDenied(String), AlreadyExists(String), NotEmpty(String), NotADirectory(String), IsADirectory(String), Unsupported(String), Io(String), UnexpectedEof, } impl std::fmt::Display for VfsError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { VfsError::NotFound(p) => write!(f, "No such file or directory: {}", p), VfsError::PermissionDenied(p) => write!(f, "Permission denied: {}", p), VfsError::AlreadyExists(p) => write!(f, "File already exists: {}", p), VfsError::NotEmpty(p) => write!(f, "Directory not empty: {}", p), VfsError::NotADirectory(p) => write!(f, "Not a directory: {}", p), VfsError::IsADirectory(p) => write!(f, "Is a directory: {}", p), VfsError::Unsupported(msg) => write!(f, "Unsupported: {}", msg), VfsError::Io(msg) => write!(f, "IO error: {}", msg), VfsError::UnexpectedEof => write!(f, "Unexpected end of file"), } } } impl std::error::Error for VfsError {} /// 文件统计信息(类似 libc::stat) #[derive(Debug, Clone)] pub struct VfsStat { pub size: u64, pub mode: u32, pub uid: u32, pub gid: u32, pub atime: SystemTime, pub mtime: SystemTime, pub is_dir: bool, pub is_symlink: bool, } impl VfsStat { pub fn new() -> Self { Self { size: 0, mode: 0, uid: 0, gid: 0, atime: SystemTime::UNIX_EPOCH, mtime: SystemTime::UNIX_EPOCH, is_dir: false, is_symlink: false, } } } impl Default for VfsStat { fn default() -> Self { Self::new() } } /// 目录条目 #[derive(Debug, Clone)] pub struct VfsDirEntry { pub name: String, pub long_name: String, pub stat: VfsStat, } /// 打开文件的抽象 pub trait VfsFile { fn read(&mut self, buf: &mut [u8]) -> Result; fn write(&mut self, buf: &[u8]) -> Result; fn seek(&mut self, pos: std::io::SeekFrom) -> Result; fn flush(&mut self) -> Result<(), VfsError>; fn stat(&mut self) -> Result; fn set_len(&mut self, size: u64) -> Result<(), VfsError>; /// Write all bytes (convenience, default loops write() until done) fn write_all(&mut self, mut buf: &[u8]) -> Result<(), VfsError> { while !buf.is_empty() { let n = self.write(buf)?; if n == 0 { return Err(VfsError::Io("write returned 0".to_string())); } buf = &buf[n..]; } Ok(()) } /// Read exactly `buf.len()` bytes (convenience, loops read() until done) fn read_exact(&mut self, mut buf: &mut [u8]) -> Result<(), VfsError> { while !buf.is_empty() { let n = self.read(buf)?; if n == 0 { return Err(VfsError::UnexpectedEof); } buf = &mut buf[n..]; } Ok(()) } } /// VFS 后端 trait(所有文件系统操作) pub trait VfsBackend: Send { /// 读取目录内容 fn read_dir(&self, path: &Path) -> Result, VfsError>; /// 打开文件(读/写) fn open_file(&self, path: &Path, flags: &open_flags::OpenFlags) -> Result, VfsError>; /// 获取文件/目录元数据 fn stat(&self, path: &Path) -> Result; fn lstat(&self, path: &Path) -> Result; /// 创建目录 fn create_dir(&self, path: &Path, mode: u32) -> Result<(), VfsError>; /// 递归创建目录 fn create_dir_all(&self, path: &Path, mode: u32) -> Result<(), VfsError>; /// 删除空目录 fn remove_dir(&self, path: &Path) -> Result<(), VfsError>; /// 删除文件 fn remove_file(&self, path: &Path) -> Result<(), VfsError>; /// 重命名 fn rename(&self, from: &Path, to: &Path) -> Result<(), VfsError>; /// 设置文件属性 fn set_stat(&self, path: &Path, stat: &VfsStat) -> Result<(), VfsError>; /// 读取符号链接目标 fn read_link(&self, path: &Path) -> Result; /// 创建符号链接 fn create_symlink(&self, target: &Path, link: &Path) -> Result<(), VfsError>; /// 规范化路径 fn real_path(&self, path: &Path) -> Result; /// 检查路径是否存在 fn exists(&self, path: &Path) -> bool; /// 创建硬链接 fn hard_link(&self, original: &Path, link: &Path) -> Result<(), VfsError>; }