feat(phase95.5): Ring0統合完了 - Adapter整理とコード簡略化
Phase 95.5完全達成 - ConsoleService/StringService Ring0直結化 ### 実装成果 - ✅ ConsoleBoxAdapter Ring0直結(println → log.info, print → io.stdout_write) - ✅ StringBoxAdapter 純粋関数化(Box状態不要) - ✅ #[allow(dead_code)] 6→4箇所削減(2削除) - ✅ PluginHost初期化簡略化(存在確認のみ) - ✅ テスト14/14 PASS(100%) ### 変更ファイル - src/runtime/core_services.rs: ConsoleBoxAdapter/StringBoxAdapter unit struct化 - src/runtime/plugin_host.rs: 初期化ロジック簡略化(create_box → has_type) - docs/development/current/main/core_boxes_design.md: Section 12追加 - CURRENT_TASK.md: Phase 95.5成果記録 ### 設計パターン確立 **2つのAdapterパターン**: 1. Ring0直結型(ConsoleService): OS API thin wrapper 2. 純粋関数型(StringService): Box状態不要 **将来実装方針**: - ArrayService/MapService: 状態管理必要 → Box保持 - IntegerService/BoolService: 純粋関数 → Box不要 ### 技術的成果 - Ring0統合完成(ログ経路統一: Ring0 → Ring1-Core → 実行パス) - コード簡略化(不要なinnerフィールド削除) - 設計明確化(Adapterの役割を2パターンに整理) - テスト容易性向上(Ring0モック可能) ### 削減統計 - #[allow(dead_code)]: 2箇所削除 - innerフィールド: 2個削除 - Box依存: 2箇所削除 ### 次のステップ Phase 96: ArrayService/MapService実装(downcastパターン) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -106,25 +106,30 @@ impl CoreServices {
|
||||
// ============================================================================
|
||||
|
||||
/// StringBox → StringService Adapter
|
||||
pub struct StringBoxAdapter {
|
||||
#[allow(dead_code)]
|
||||
inner: Box<dyn NyashBox>,
|
||||
}
|
||||
///
|
||||
/// Phase 95.5: 純粋関数設計
|
||||
/// - Box を保持せず、純粋関数として実装
|
||||
/// - len(s) → s.chars().count() (UTF-8 文字数)
|
||||
/// - Phase 96 以降で substring(), concat() など追加予定
|
||||
pub struct StringBoxAdapter;
|
||||
|
||||
impl StringBoxAdapter {
|
||||
pub fn new(box_instance: Box<dyn NyashBox>) -> Self {
|
||||
Self { inner: box_instance }
|
||||
pub fn new() -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
||||
impl StringService for StringBoxAdapter {
|
||||
fn len(&self, s: &str) -> i64 {
|
||||
// Phase 95: 文字列長を返す(UTF-8 バイト数ではなく文字数)
|
||||
// Phase 95.5: 文字列長を返す(UTF-8 バイト数ではなく文字数)
|
||||
s.chars().count() as i64
|
||||
}
|
||||
}
|
||||
|
||||
/// IntegerBox → IntegerService Adapter
|
||||
///
|
||||
/// Phase 95.5: inner フィールドは #[allow(dead_code)] のまま保持
|
||||
/// Phase 96 以降で実装時に、Box 状態が必要か純粋関数で足りるか判断
|
||||
pub struct IntegerBoxAdapter {
|
||||
#[allow(dead_code)]
|
||||
inner: Box<dyn NyashBox>,
|
||||
@ -137,10 +142,13 @@ impl IntegerBoxAdapter {
|
||||
}
|
||||
|
||||
impl IntegerService for IntegerBoxAdapter {
|
||||
// Phase 95 以降で実装
|
||||
// Phase 96 以降で実装
|
||||
}
|
||||
|
||||
/// BoolBox → BoolService Adapter
|
||||
///
|
||||
/// Phase 95.5: inner フィールドは #[allow(dead_code)] のまま保持
|
||||
/// Phase 96 以降で実装時に、Box 状態が必要か純粋関数で足りるか判断
|
||||
pub struct BoolBoxAdapter {
|
||||
#[allow(dead_code)]
|
||||
inner: Box<dyn NyashBox>,
|
||||
@ -153,10 +161,13 @@ impl BoolBoxAdapter {
|
||||
}
|
||||
|
||||
impl BoolService for BoolBoxAdapter {
|
||||
// Phase 95 以降で実装
|
||||
// Phase 96 以降で実装
|
||||
}
|
||||
|
||||
/// ArrayBox → ArrayService Adapter
|
||||
///
|
||||
/// Phase 95.5: inner フィールドは #[allow(dead_code)] のまま保持
|
||||
/// Phase 96 以降で実装時に、Box 状態が必要か純粋関数で足りるか判断
|
||||
pub struct ArrayBoxAdapter {
|
||||
#[allow(dead_code)]
|
||||
inner: Box<dyn NyashBox>,
|
||||
@ -169,10 +180,13 @@ impl ArrayBoxAdapter {
|
||||
}
|
||||
|
||||
impl ArrayService for ArrayBoxAdapter {
|
||||
// Phase 95 以降で実装
|
||||
// Phase 96 以降で実装
|
||||
}
|
||||
|
||||
/// MapBox → MapService Adapter
|
||||
///
|
||||
/// Phase 95.5: inner フィールドは #[allow(dead_code)] のまま保持
|
||||
/// Phase 96 以降で実装時に、Box 状態が必要か純粋関数で足りるか判断
|
||||
pub struct MapBoxAdapter {
|
||||
#[allow(dead_code)]
|
||||
inner: Box<dyn NyashBox>,
|
||||
@ -185,31 +199,36 @@ impl MapBoxAdapter {
|
||||
}
|
||||
|
||||
impl MapService for MapBoxAdapter {
|
||||
// Phase 95 以降で実装
|
||||
// Phase 96 以降で実装
|
||||
}
|
||||
|
||||
/// ConsoleBox → ConsoleService Adapter
|
||||
pub struct ConsoleBoxAdapter {
|
||||
#[allow(dead_code)]
|
||||
inner: Box<dyn NyashBox>,
|
||||
}
|
||||
///
|
||||
/// Phase 95.5: Ring0 直結設計
|
||||
/// - Box を保持せず、Ring0Context に直結
|
||||
/// - println() → Ring0Context.log.info()
|
||||
/// - print() → Ring0Context.io.stdout_write()
|
||||
pub struct ConsoleBoxAdapter;
|
||||
|
||||
impl ConsoleBoxAdapter {
|
||||
pub fn new(box_instance: Box<dyn NyashBox>) -> Self {
|
||||
Self { inner: box_instance }
|
||||
pub fn new() -> Self {
|
||||
Self
|
||||
}
|
||||
}
|
||||
|
||||
impl ConsoleService for ConsoleBoxAdapter {
|
||||
fn println(&self, msg: &str) {
|
||||
// Phase 95: ConsoleBox の println 機能を使用
|
||||
// ConsoleBox は直接 println! を呼ぶだけなので、ここでも同様に実装
|
||||
println!("{}", msg);
|
||||
// Phase 95.5: Ring0Context 経由でログ出力(自動改行)
|
||||
use crate::runtime::ring0::get_global_ring0;
|
||||
let ring0 = get_global_ring0();
|
||||
ring0.log.info(msg);
|
||||
}
|
||||
|
||||
fn print(&self, msg: &str) {
|
||||
// Phase 95: ConsoleBox の print 機能を使用
|
||||
print!("{}", msg);
|
||||
// Phase 95.5: Ring0Context 経由で stdout 出力(改行なし)
|
||||
use crate::runtime::ring0::get_global_ring0;
|
||||
let ring0 = get_global_ring0();
|
||||
ring0.io.stdout_write(msg.as_bytes()).ok();
|
||||
}
|
||||
}
|
||||
|
||||
@ -236,36 +255,46 @@ mod tests {
|
||||
assert!(required.contains(&CoreBoxId::Console));
|
||||
}
|
||||
|
||||
// Phase 95.5: Ring0 初期化ヘルパー(テスト用)
|
||||
#[cfg(test)]
|
||||
fn ensure_ring0_initialized() {
|
||||
use crate::runtime::ring0::{default_ring0, GLOBAL_RING0};
|
||||
use std::sync::Arc;
|
||||
|
||||
// 既に初期化済みなら何もしない
|
||||
if GLOBAL_RING0.get().is_none() {
|
||||
GLOBAL_RING0.set(Arc::new(default_ring0())).ok();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_console_service_println() {
|
||||
use crate::boxes::console_box::ConsoleBox;
|
||||
// Phase 95.5: Ring0 初期化(安全な初期化)
|
||||
ensure_ring0_initialized();
|
||||
|
||||
let console_box = Box::new(ConsoleBox::new()) as Box<dyn NyashBox>;
|
||||
let adapter = ConsoleBoxAdapter::new(console_box);
|
||||
let adapter = ConsoleBoxAdapter::new();
|
||||
|
||||
// Phase 95: println を呼び出し(panic しないことを確認)
|
||||
adapter.println("Test message");
|
||||
// Phase 95.5: println を呼び出し(Ring0 経由、panic しないことを確認)
|
||||
adapter.println("Test message from Ring0");
|
||||
// 実際の出力検証は Phase 96 以降
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_console_service_print() {
|
||||
use crate::boxes::console_box::ConsoleBox;
|
||||
// Phase 95.5: Ring0 初期化(安全な初期化)
|
||||
ensure_ring0_initialized();
|
||||
|
||||
let console_box = Box::new(ConsoleBox::new()) as Box<dyn NyashBox>;
|
||||
let adapter = ConsoleBoxAdapter::new(console_box);
|
||||
let adapter = ConsoleBoxAdapter::new();
|
||||
|
||||
// Phase 95: print を呼び出し(panic しないことを確認)
|
||||
adapter.print("Test message");
|
||||
// Phase 95.5: print を呼び出し(Ring0 経由、panic しないことを確認)
|
||||
adapter.print("No newline");
|
||||
// 実際の出力検証は Phase 96 以降
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_string_service_len() {
|
||||
use crate::boxes::string_box::StringBox;
|
||||
|
||||
let string_box = Box::new(StringBox::new("Hello")) as Box<dyn NyashBox>;
|
||||
let adapter = StringBoxAdapter::new(string_box);
|
||||
// Phase 95.5: 純粋関数なので Ring0 不要
|
||||
let adapter = StringBoxAdapter::new();
|
||||
|
||||
// Phase 95: len を呼び出し
|
||||
let length = adapter.len("Hello");
|
||||
@ -275,4 +304,17 @@ mod tests {
|
||||
let length_utf8 = adapter.len("こんにちは");
|
||||
assert_eq!(length_utf8, 5); // 5文字(バイト数は15)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_console_service_ring0_integration() {
|
||||
// Phase 95.5: Ring0 初期化(安全な初期化)
|
||||
ensure_ring0_initialized();
|
||||
|
||||
// ConsoleService 経由で出力(Ring0 使用)
|
||||
let adapter = ConsoleBoxAdapter::new();
|
||||
adapter.println("Test message from Ring0");
|
||||
adapter.print("No newline");
|
||||
|
||||
// panic しないことを確認
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,14 +100,14 @@ impl PluginHost {
|
||||
|
||||
// Phase 94: 各 core_required Box を取得して Adapter に変換
|
||||
|
||||
// StringBox
|
||||
let string_box = registry
|
||||
.create_box("StringBox", &[])
|
||||
.map_err(|e| CoreInitError::MissingService {
|
||||
// StringBox (Phase 95.5: 純粋関数化、存在チェックのみ)
|
||||
if !registry.has_type("StringBox") {
|
||||
return Err(CoreInitError::MissingService {
|
||||
box_id: CoreBoxId::String,
|
||||
message: format!("StringBox creation failed: {}", e),
|
||||
})?;
|
||||
let string_service = Arc::new(StringBoxAdapter::new(string_box));
|
||||
message: "StringBox not found in registry".to_string(),
|
||||
});
|
||||
}
|
||||
let string_service = Arc::new(StringBoxAdapter::new());
|
||||
|
||||
// IntegerBox
|
||||
let integer_box = registry
|
||||
@ -145,14 +145,14 @@ impl PluginHost {
|
||||
})?;
|
||||
let map_service = Arc::new(MapBoxAdapter::new(map_box));
|
||||
|
||||
// ConsoleBox
|
||||
let console_box = registry
|
||||
.create_box("ConsoleBox", &[])
|
||||
.map_err(|e| CoreInitError::MissingService {
|
||||
// ConsoleBox (Phase 95.5: Ring0 直結、存在チェックのみ)
|
||||
if !registry.has_type("ConsoleBox") {
|
||||
return Err(CoreInitError::MissingService {
|
||||
box_id: CoreBoxId::Console,
|
||||
message: format!("ConsoleBox creation failed: {}", e),
|
||||
})?;
|
||||
let console_service = Arc::new(ConsoleBoxAdapter::new(console_box));
|
||||
message: "ConsoleBox not found in registry".to_string(),
|
||||
});
|
||||
}
|
||||
let console_service = Arc::new(ConsoleBoxAdapter::new());
|
||||
|
||||
// Phase 94: 実際の Adapter を使用して CoreServices を構築
|
||||
let core = CoreServices {
|
||||
@ -277,7 +277,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_with_core_from_registry_missing_box() {
|
||||
// Phase 94: registry が空の場合はエラーを返すことを確認
|
||||
// Phase 95.5: registry が空の場合はエラーを返すことを確認
|
||||
use crate::runtime::ring0::default_ring0;
|
||||
let ring0 = Arc::new(default_ring0());
|
||||
let registry = UnifiedBoxRegistry::new();
|
||||
@ -285,13 +285,13 @@ mod tests {
|
||||
let result = PluginHost::with_core_from_registry(ring0, ®istry);
|
||||
assert!(result.is_err());
|
||||
|
||||
// Phase 94: エラーメッセージに "creation failed" または "Unknown Box type" が含まれることを確認
|
||||
// Phase 95.5: エラーメッセージに "not found in registry" が含まれることを確認
|
||||
if let Err(e) = result {
|
||||
let msg = format!("{}", e);
|
||||
eprintln!("Error message: {}", msg); // デバッグ出力
|
||||
assert!(
|
||||
msg.contains("creation failed") || msg.contains("Unknown Box type"),
|
||||
"Error message should contain 'creation failed' or 'Unknown Box type', got: {}",
|
||||
msg.contains("not found in registry") || msg.contains("creation failed") || msg.contains("Unknown Box type"),
|
||||
"Error message should contain 'not found in registry', 'creation failed' or 'Unknown Box type', got: {}",
|
||||
msg
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user