feat(phase112): Ring0 Service Registry統一化実装完了
Ring0 初期化を Ring0Registry::build(profile) に集約し、プロファイル対応を統一化 【実装内容】 - Task 2: Ring0Registry struct + build(profile) メソッド実装 - RuntimeProfile::Default → StdFs を使用 - RuntimeProfile::NoFs → NoFsApi を使用 - build_default()/build_no_fs() の内部メソッド分離 - Task 3: NoFsApi struct 実装(FsApi trait) - すべてのファイルシステム操作を「disabled」として失敗させる - read/write/append/metadata/canonicalize が IoError を返す - exists() は false を返す - 49行の新規実装 - Task 4: initialize_runtime() SSOT パターン確認 - env 読み込み → RuntimeProfile::from_env() - Ring0Context 構築 → Ring0Registry::build(profile) - グローバル登録 → init_global_ring0() - 唯一の責務分離を確立 - Task 5: PluginHost/FileBox/FileHandleBox からの Ring0 統合 - Ring0.fs = NoFsApi の場合、すべての上位層が自動的に disabled - 特別なロジック不要(カスケード disabled パターン) - Task 6: ドキュメント更新 - core_boxes_design.md: Section 17 追加(88行) - ring0-inventory.md: Phase 112 エントリ追加(16行) - CURRENT_TASK.md: Phase 106-112 完了表更新 - phase112_ring0_registry_design.md: 完全設計書(426行) 【統計】 - 8ファイル修正(+261行, -30行) - 3つの新テスト追加(Ring0Registry関連) - test_ring0_registry_default_profile - test_ring0_registry_nofs_profile - test_default_ring0_uses_registry - cargo build --release: SUCCESS - 全テスト PASS 【設計原則確立】 - Ring0Registry factory pattern で profile-aware 実装選択を一本化 - NoFsApi による自動 disabled により、上位層の特別処理を排除 - initialize_runtime() が唯一の env 読み込み入口として SSOT 確立 - 将来の profile 追加(TestMock/Sandbox/ReadOnly/Embedded等)が容易に 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -7,11 +7,12 @@ mod std_impls;
|
||||
mod traits;
|
||||
|
||||
pub use errors::{IoError, TimeError};
|
||||
pub use std_impls::{NoopMem, StdFs, StdIo, StdLog, StdMem, StdThread, StdTime};
|
||||
pub use std_impls::{NoopMem, NoFsApi, StdFs, StdIo, StdLog, StdMem, StdThread, StdTime};
|
||||
pub use traits::{
|
||||
FsApi, FsMetadata, IoApi, LogApi, LogLevel, MemApi, MemStats, ThreadApi, TimeApi,
|
||||
};
|
||||
|
||||
use crate::runtime::runtime_profile::RuntimeProfile;
|
||||
use std::sync::{Arc, OnceLock};
|
||||
|
||||
/// Phase 88: Ring0 コンテキスト
|
||||
@ -60,16 +61,51 @@ impl std::fmt::Debug for Ring0Context {
|
||||
}
|
||||
}
|
||||
|
||||
/// デフォルト Ring0Context を作成(std ベース)
|
||||
pub fn default_ring0() -> Ring0Context {
|
||||
Ring0Context {
|
||||
mem: Arc::new(StdMem::new()),
|
||||
io: Arc::new(StdIo),
|
||||
time: Arc::new(StdTime),
|
||||
log: Arc::new(StdLog),
|
||||
fs: Arc::new(StdFs),
|
||||
thread: Arc::new(StdThread),
|
||||
/// Phase 112: Ring0 service registry
|
||||
///
|
||||
/// profile ごとに適切な FsApi 実装(等)を選択して Ring0Context を構築する factory。
|
||||
pub struct Ring0Registry;
|
||||
|
||||
impl Ring0Registry {
|
||||
/// Ring0Context を profile に応じて構築
|
||||
pub fn build(profile: RuntimeProfile) -> Ring0Context {
|
||||
match profile {
|
||||
RuntimeProfile::Default => Self::build_default(),
|
||||
RuntimeProfile::NoFs => Self::build_no_fs(),
|
||||
}
|
||||
}
|
||||
|
||||
fn build_default() -> Ring0Context {
|
||||
Ring0Context {
|
||||
mem: Arc::new(StdMem::new()),
|
||||
io: Arc::new(StdIo),
|
||||
time: Arc::new(StdTime),
|
||||
log: Arc::new(StdLog),
|
||||
fs: Arc::new(StdFs),
|
||||
thread: Arc::new(StdThread),
|
||||
}
|
||||
}
|
||||
|
||||
fn build_no_fs() -> Ring0Context {
|
||||
Ring0Context {
|
||||
mem: Arc::new(StdMem::new()),
|
||||
io: Arc::new(StdIo),
|
||||
time: Arc::new(StdTime),
|
||||
log: Arc::new(StdLog),
|
||||
fs: Arc::new(NoFsApi), // Phase 112: NoFs profile では FsApi を disabled に
|
||||
thread: Arc::new(StdThread),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Phase 88: デフォルト Ring0Context を作成
|
||||
///
|
||||
/// Phase 112 以降は、initialize_runtime() を通じて
|
||||
/// Ring0Registry::build(profile) 経由で初期化されることが推奨。
|
||||
///
|
||||
/// この関数は直接呼び出しに対する互換性レイヤーとして保持。
|
||||
pub fn default_ring0() -> Ring0Context {
|
||||
Ring0Registry::build(RuntimeProfile::Default)
|
||||
}
|
||||
|
||||
// ===== グローバル Ring0Context =====
|
||||
@ -144,4 +180,41 @@ mod tests {
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
// Phase 112: Ring0Registry tests
|
||||
#[test]
|
||||
fn test_ring0_registry_default_profile() {
|
||||
let ctx = Ring0Registry::build(RuntimeProfile::Default);
|
||||
|
||||
// Verify basic operations work
|
||||
ctx.log.info("Test message from Default profile");
|
||||
assert!(ctx.time.now().is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ring0_registry_nofs_profile() {
|
||||
use std::path::Path;
|
||||
|
||||
let ctx = Ring0Registry::build(RuntimeProfile::NoFs);
|
||||
|
||||
// Verify NoFsApi returns errors
|
||||
let result = ctx.fs.read_to_string(Path::new("/tmp/test.txt"));
|
||||
assert!(result.is_err());
|
||||
|
||||
// Verify exists returns false
|
||||
assert!(!ctx.fs.exists(Path::new("/tmp/test.txt")));
|
||||
|
||||
// Other services should still work
|
||||
ctx.log.info("Test message from NoFs profile");
|
||||
assert!(ctx.time.now().is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_default_ring0_uses_registry() {
|
||||
let ctx = default_ring0();
|
||||
|
||||
// Should behave same as Default profile
|
||||
ctx.log.info("Test from default_ring0()");
|
||||
assert!(ctx.time.now().is_ok());
|
||||
}
|
||||
}
|
||||
|
||||
@ -227,6 +227,55 @@ impl ThreadApi for StdThread {
|
||||
}
|
||||
}
|
||||
|
||||
/// Phase 112: No-FS profile 用 FsApi stub
|
||||
///
|
||||
/// FileSystem 操作がすべて「無効」として機能する。
|
||||
/// Phase 109 の NoFsFileIo(FileIo trait)と異なり、
|
||||
/// Ring0 レベルの FsApi trait を実装する。
|
||||
pub struct NoFsApi;
|
||||
|
||||
impl FsApi for NoFsApi {
|
||||
fn read_to_string(&self, _path: &Path) -> Result<String, IoError> {
|
||||
Err(IoError::Other(
|
||||
"FileSystem operations disabled in no-fs profile".to_string()
|
||||
))
|
||||
}
|
||||
|
||||
fn read(&self, _path: &Path) -> Result<Vec<u8>, IoError> {
|
||||
Err(IoError::Other(
|
||||
"FileSystem operations disabled in no-fs profile".to_string()
|
||||
))
|
||||
}
|
||||
|
||||
fn write_all(&self, _path: &Path, _data: &[u8]) -> Result<(), IoError> {
|
||||
Err(IoError::Other(
|
||||
"FileSystem operations disabled in no-fs profile".to_string()
|
||||
))
|
||||
}
|
||||
|
||||
fn append_all(&self, _path: &Path, _data: &[u8]) -> Result<(), IoError> {
|
||||
Err(IoError::Other(
|
||||
"FileSystem operations disabled in no-fs profile".to_string()
|
||||
))
|
||||
}
|
||||
|
||||
fn exists(&self, _path: &Path) -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
fn metadata(&self, _path: &Path) -> Result<FsMetadata, IoError> {
|
||||
Err(IoError::Other(
|
||||
"FileSystem operations disabled in no-fs profile".to_string()
|
||||
))
|
||||
}
|
||||
|
||||
fn canonicalize(&self, _path: &Path) -> Result<PathBuf, IoError> {
|
||||
Err(IoError::Other(
|
||||
"FileSystem operations disabled in no-fs profile".to_string()
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
// ===== テスト (Phase 102) =====
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user