Files
hakorune/src/boxes/file/mod.rs
nyash-codex f9d100ce01 chore: Phase 25.1 完了 - LoopForm v2/Stage1 CLI/環境変数削減 + Phase 26-D からの変更
Phase 25.1 完了成果:
-  LoopForm v2 テスト・ドキュメント・コメント完備
  - 4ケース(A/B/C/D)完全テストカバレッジ
  - 最小再現ケース作成(SSAバグ調査用)
  - SSOT文書作成(loopform_ssot.md)
  - 全ソースに [LoopForm] コメントタグ追加

-  Stage-1 CLI デバッグ環境構築
  - stage1_cli.hako 実装
  - stage1_bridge.rs ブリッジ実装
  - デバッグツール作成(stage1_debug.sh/stage1_minimal.sh)
  - アーキテクチャ改善提案文書

-  環境変数削減計画策定
  - 25変数の完全調査・分類
  - 6段階削減ロードマップ(25→5、80%削減)
  - 即時削除可能変数特定(NYASH_CONFIG/NYASH_DEBUG)

Phase 26-D からの累積変更:
- PHI実装改善(ExitPhiBuilder/HeaderPhiBuilder等)
- MIRビルダーリファクタリング
- 型伝播・最適化パス改善
- その他約300ファイルの累積変更

🎯 技術的成果:
- SSAバグ根本原因特定(条件分岐内loop変数変更)
- Region+next_iパターン適用完了(UsingCollectorBox等)
- LoopFormパターン文書化・テスト化完了
- セルフホスティング基盤強化

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: ChatGPT <noreply@openai.com>
Co-Authored-By: Task Assistant <task@anthropic.com>
2025-11-21 06:25:17 +09:00

225 lines
6.5 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//! FileBox 📁 - ファイルI/OPathBox/DirBoxとセット
// Nyashの箱システムによるファイル入出力を提供します。
// 参考: 既存Boxの設計思想
// SSOT provider design (ring0/1) — modules are currently placeholders
pub mod box_shim; // Thin delegating shim
pub mod builtin_factory;
pub mod core_ro; // Core readonly provider
pub mod provider; // trait FileIo / FileCaps / FileError // 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<Arc<dyn FileIo>>,
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", &"<FileIo>")
.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<dyn FileIo>) -> Self {
FileBox {
provider: Some(provider),
path: String::new(),
base: BoxBase::new(),
}
}
pub fn open(path: &str) -> Result<Self, String> {
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<String, String> {
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> {
// Fail-Fast by capability: consult provider caps
let caps = self
.provider
.as_ref()
.map(|p| p.caps())
.or_else(|| provider_lock::get_filebox_caps())
.unwrap_or_else(|| provider::FileCaps::read_only());
if !caps.write {
return Err("Write unsupported by current FileBox provider (read-only)".to_string());
}
// Write-capable provider not wired yet
Err("Write supported by provider but not implemented in this build".to_string())
}
/// ファイルの内容を読み取る
pub fn read(&self) -> Box<dyn NyashBox> {
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<dyn NyashBox>) -> Box<dyn NyashBox> {
let caps = self
.provider
.as_ref()
.map(|p| p.caps())
.or_else(|| provider_lock::get_filebox_caps())
.unwrap_or_else(|| provider::FileCaps::read_only());
if !caps.write {
return Box::new(StringBox::new(
"Error: write unsupported by provider (read-only)",
));
}
Box::new(StringBox::new(
"Error: write supported but not implemented in this build",
))
}
/// ファイルが存在するかチェック
pub fn exists(&self) -> Box<dyn NyashBox> {
use std::path::Path;
Box::new(BoolBox::new(Path::new(&self.path).exists()))
}
/// ファイルを削除
pub fn delete(&self) -> Box<dyn NyashBox> {
let caps = self
.provider
.as_ref()
.map(|p| p.caps())
.or_else(|| provider_lock::get_filebox_caps())
.unwrap_or_else(|| provider::FileCaps::read_only());
if !caps.write {
return Box::new(StringBox::new(
"Error: delete unsupported by provider (read-only)",
));
}
Box::new(StringBox::new(
"Error: delete supported but not implemented in this build",
))
}
/// ファイルをコピー
pub fn copy(&self, _dest: &str) -> Box<dyn NyashBox> {
let caps = self
.provider
.as_ref()
.map(|p| p.caps())
.or_else(|| provider_lock::get_filebox_caps())
.unwrap_or_else(|| provider::FileCaps::read_only());
if !caps.write {
return Box::new(StringBox::new(
"Error: copy unsupported by provider (read-only)",
));
}
Box::new(StringBox::new(
"Error: copy supported but not implemented in this build",
))
}
}
impl BoxCore for FileBox {
fn box_id(&self) -> u64 {
self.base.id
}
fn parent_type_id(&self) -> Option<std::any::TypeId> {
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<dyn NyashBox> {
// Clone by copying provider and path reference
Box::new(self.clone())
}
/// 仮実装: clone_boxと同じ後で修正
fn share_box(&self) -> Box<dyn NyashBox> {
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::<FileBox>() {
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)
}
}