//! FileBox 📁 - ファイルI/O(PathBox/DirBoxとセット) // Nyashの箱システムによるファイル入出力を提供します。 // 参考: 既存Boxの設計思想 // SSOT provider design (ring‑0/1) — modules are currently placeholders pub mod provider; // trait FileIo / FileCaps / FileError pub mod core_ro; // Core read‑only provider pub mod box_shim; // Thin delegating shim pub mod builtin_factory; // Builtin FileBox ProviderFactory use crate::box_trait::{BoolBox, BoxBase, BoxCore, NyashBox, StringBox}; use crate::runtime::provider_lock; use std::any::Any; use std::sync::Arc; use self::provider::FileIo; pub struct FileBox { provider: Option>, path: String, base: BoxBase, } impl std::fmt::Debug for FileBox { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("FileBox") .field("path", &self.path) .field("provider", &"") .finish() } } impl Clone for FileBox { fn clone(&self) -> Self { // Clone by copying provider reference and path FileBox { provider: self.provider.clone(), path: self.path.clone(), base: BoxBase::new(), } } } impl FileBox { pub fn new() -> Self { FileBox { provider: provider_lock::get_filebox_provider().cloned(), path: String::new(), base: BoxBase::new(), } } /// Create FileBox with explicit provider (for builtin fallback) pub fn with_provider(provider: Arc) -> Self { FileBox { provider: Some(provider), path: String::new(), base: BoxBase::new(), } } pub fn open(path: &str) -> Result { let provider = provider_lock::get_filebox_provider() .ok_or("FileBox provider not initialized")? .clone(); provider.open(path) .map_err(|e| format!("Failed to open: {}", e))?; Ok(FileBox { provider: Some(provider), path: path.to_string(), base: BoxBase::new(), }) } pub fn read_to_string(&self) -> Result { if let Some(ref provider) = self.provider { provider.read() .map_err(|e| format!("Read failed: {}", e)) } else { Err("No provider available".to_string()) } } pub fn write_all(&self, _buf: &[u8]) -> Result<(), String> { // CoreRo does not support write - Fail-Fast Err("Write operation not supported in read-only mode".to_string()) } /// ファイルの内容を読み取る pub fn read(&self) -> Box { match self.read_to_string() { Ok(content) => Box::new(StringBox::new(&content)), Err(e) => Box::new(StringBox::new(&format!("Error reading file: {}", e))), } } /// ファイルに内容を書き込む pub fn write(&self, _content: Box) -> Box { // Fail-Fast: CoreRo does not support write Box::new(StringBox::new("Error: Write operation not supported in read-only mode")) } /// ファイルが存在するかチェック pub fn exists(&self) -> Box { use std::path::Path; Box::new(BoolBox::new(Path::new(&self.path).exists())) } /// ファイルを削除 pub fn delete(&self) -> Box { // Fail-Fast: CoreRo does not support delete Box::new(StringBox::new("Error: Delete operation not supported in read-only mode")) } /// ファイルをコピー pub fn copy(&self, _dest: &str) -> Box { // Fail-Fast: CoreRo does not support copy Box::new(StringBox::new("Error: Copy operation not supported in read-only mode")) } } impl BoxCore for FileBox { fn box_id(&self) -> u64 { self.base.id } fn parent_type_id(&self) -> Option { self.base.parent_type_id } fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "FileBox({})", self.path) } fn as_any(&self) -> &dyn Any { self } fn as_any_mut(&mut self) -> &mut dyn Any { self } } impl NyashBox for FileBox { fn clone_box(&self) -> Box { // Clone by copying provider and path reference Box::new(self.clone()) } /// 仮実装: clone_boxと同じ(後で修正) fn share_box(&self) -> Box { self.clone_box() } fn to_string_box(&self) -> StringBox { StringBox::new(format!("FileBox({})", self.path)) } fn type_name(&self) -> &'static str { "FileBox" } fn equals(&self, other: &dyn NyashBox) -> BoolBox { if let Some(other_file) = other.as_any().downcast_ref::() { BoolBox::new(self.path == other_file.path) } else { BoolBox::new(false) } } } impl std::fmt::Display for FileBox { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.fmt_box(f) } }