use std::fs; use std::path::Path; use crate::model::cartridge::{Cartridge, CartridgeDTO, CartridgeError, CartridgeManifest}; pub struct CartridgeLoader; impl CartridgeLoader { pub fn load(path: impl AsRef) -> Result { let path = path.as_ref(); if !path.exists() { return Err(CartridgeError::NotFound); } if path.is_dir() { DirectoryCartridgeLoader::load(path) } else if path.extension().is_some_and(|ext| ext == "pmc") { PackedCartridgeLoader::load(path) } else { Err(CartridgeError::InvalidFormat) } } } pub struct DirectoryCartridgeLoader; impl DirectoryCartridgeLoader { pub fn load(path: &Path) -> Result { let manifest_path = path.join("manifest.json"); if !manifest_path.exists() { return Err(CartridgeError::InvalidManifest); } let manifest_content = fs::read_to_string(manifest_path).map_err(|_| CartridgeError::IoError)?; let manifest: CartridgeManifest = serde_json::from_str(&manifest_content).map_err(|_| CartridgeError::InvalidManifest)?; // Validação adicional conforme requisitos if manifest.magic != "PMTU" { return Err(CartridgeError::InvalidManifest); } if manifest.cartridge_version != 1 { return Err(CartridgeError::UnsupportedVersion); } let program_path = path.join("program.pbc"); if !program_path.exists() { return Err(CartridgeError::MissingProgram); } let program = fs::read(program_path).map_err(|_| CartridgeError::IoError)?; let assets_path = path.join("assets"); let assets_path = if assets_path.exists() && assets_path.is_dir() { Some(assets_path) } else { None }; let dto = CartridgeDTO { app_id: manifest.app_id, title: manifest.title, app_version: manifest.app_version, app_mode: manifest.app_mode, entrypoint: manifest.entrypoint, program, assets_path, }; Ok(Cartridge::from(dto)) } } pub struct PackedCartridgeLoader; impl PackedCartridgeLoader { pub fn load(_path: &Path) -> Result { // Stub inicialmente, como solicitado Err(CartridgeError::InvalidFormat) } }