pub mod device; pub mod disc_image; use thiserror::Error; #[derive(Debug, Error)] pub enum VfsError { #[error("I/O error: {0}")] Io(#[from] std::io::Error), #[error("Invalid format: {0}")] InvalidFormat(String), #[error("File not found: {0}")] NotFound(String), } /// A virtual filesystem entry (file or directory). #[derive(Debug, Clone)] pub struct VfsEntry { pub name: String, pub is_directory: bool, pub size: u64, pub offset: u64, /// Xbox `FILE_ATTRIBUTE_*` bitmask for this entry, sourced from the /// backing device's real on-disc metadata rather than inferred from /// the path shape. For GDFX disc images this is the on-disc attribute /// byte at dirent offset +12 OR'd with `FILE_ATTRIBUTE_READONLY` /// (matches xenia-canary `disc_image_device.cc:154`: /// `entry->attributes_ = attributes | kFileAttributeReadOnly`). /// /// Bit layout (canary `vfs/entry.h:66-76`): READONLY=0x01, HIDDEN=0x02, /// SYSTEM=0x04, DIRECTORY=0x10, ARCHIVE=0x20, NORMAL=0x80. pub attributes: u32, } /// Trait for VFS device implementations (XISO, STFS, host path, etc.) pub trait VfsDevice: Send + Sync { fn name(&self) -> &str; fn list_root(&self) -> Result, VfsError>; fn read_file(&self, path: &str) -> Result, VfsError>; fn stat(&self, path: &str) -> Result; }