diff --git a/docs/development/current/main/core_boxes_design.md b/docs/development/current/main/core_boxes_design.md index fedd1062..60e1a829 100644 --- a/docs/development/current/main/core_boxes_design.md +++ b/docs/development/current/main/core_boxes_design.md @@ -1112,3 +1112,259 @@ fn test_map_service_basic_operations() { - IntegerService/BoolService 実装(純粋関数型で実装) - 代表パス拡大(5-10箇所で実用化テスト) - #[allow(dead_code)] 完全撲滅(0箇所達成) + +--- + +## 14. Phase 97: IntegerService/BoolService 実装完了 (2025-12-03) + +### 14.1 実装成果 + +**IntegerService trait 定義**: +```rust +pub trait IntegerService: Send + Sync { + fn add(&self, a: i64, b: i64) -> i64; + fn sub(&self, a: i64, b: i64) -> i64; + fn mul(&self, a: i64, b: i64) -> i64; + fn div(&self, a: i64, b: i64) -> Option; +} +``` + +**BoolService trait 定義**: +```rust +pub trait BoolService: Send + Sync { + fn not(&self, value: bool) -> bool; + fn and(&self, a: bool, b: bool) -> bool; + fn or(&self, a: bool, b: bool) -> bool; + fn xor(&self, a: bool, b: bool) -> bool; +} +``` + +### 14.2 Adapter unit struct 化 + +**IntegerBoxAdapter**: +```rust +// Phase 95.5: #[allow(dead_code)] inner フィールド +pub struct IntegerBoxAdapter { + #[allow(dead_code)] + inner: Box, +} + +// Phase 97: unit struct 化(Box状態不要) +pub struct IntegerBoxAdapter; + +impl IntegerBoxAdapter { + pub fn new() -> Self { + Self + } +} +``` + +**BoolBoxAdapter**: +```rust +// Phase 95.5: #[allow(dead_code)] inner フィールド +pub struct BoolBoxAdapter { + #[allow(dead_code)] + inner: Box, +} + +// Phase 97: unit struct 化(Box状態不要) +pub struct BoolBoxAdapter; + +impl BoolBoxAdapter { + pub fn new() -> Self { + Self + } +} +``` + +### 14.3 Service 実装 + +**IntegerService 実装**(純粋関数型): +```rust +impl IntegerService for IntegerBoxAdapter { + fn add(&self, a: i64, b: i64) -> i64 { + a.saturating_add(b) // オーバーフロー対策 + } + + fn sub(&self, a: i64, b: i64) -> i64 { + a.saturating_sub(b) // アンダーフロー対策 + } + + fn mul(&self, a: i64, b: i64) -> i64 { + a.saturating_mul(b) // オーバーフロー対策 + } + + fn div(&self, a: i64, b: i64) -> Option { + if b == 0 { + None // ゼロ除算 + } else { + Some(a / b) + } + } +} +``` + +**BoolService 実装**(純粋関数型): +```rust +impl BoolService for BoolBoxAdapter { + fn not(&self, value: bool) -> bool { + !value + } + + fn and(&self, a: bool, b: bool) -> bool { + a && b + } + + fn or(&self, a: bool, b: bool) -> bool { + a || b + } + + fn xor(&self, a: bool, b: bool) -> bool { + a ^ b + } +} +``` + +### 14.4 PluginHost 初期化更新 + +**IntegerBox 初期化**(Phase 95.5パターン): +```rust +// IntegerBox (Phase 97: 純粋関数化、存在チェックのみ) +if !registry.has_type("IntegerBox") { + return Err(CoreInitError::MissingService { + box_id: CoreBoxId::Integer, + message: "IntegerBox not found in registry".to_string(), + }); +} +let integer_service = Arc::new(IntegerBoxAdapter::new()); +``` + +**BoolBox 初期化**(Phase 95.5パターン): +```rust +// BoolBox (Phase 97: 純粋関数化、存在チェックのみ) +if !registry.has_type("BoolBox") { + return Err(CoreInitError::MissingService { + box_id: CoreBoxId::Bool, + message: "BoolBox not found in registry".to_string(), + }); +} +let bool_service = Arc::new(BoolBoxAdapter::new()); +``` + +### 14.5 テスト追加 + +**IntegerService テスト**: +```rust +#[test] +fn test_integer_service_operations() { + let adapter = IntegerBoxAdapter::new(); + + // add + assert_eq!(adapter.add(10, 20), 30); + assert_eq!(adapter.add(i64::MAX, 1), i64::MAX); // saturating + + // sub + assert_eq!(adapter.sub(20, 10), 10); + assert_eq!(adapter.sub(i64::MIN, 1), i64::MIN); // saturating + + // mul + assert_eq!(adapter.mul(5, 6), 30); + assert_eq!(adapter.mul(i64::MAX, 2), i64::MAX); // saturating + + // div + assert_eq!(adapter.div(20, 5), Some(4)); + assert_eq!(adapter.div(10, 3), Some(3)); // 整数除算 + assert_eq!(adapter.div(10, 0), None); // ゼロ除算 +} +``` + +**BoolService テスト**: +```rust +#[test] +fn test_bool_service_operations() { + let adapter = BoolBoxAdapter::new(); + + // not + assert_eq!(adapter.not(true), false); + assert_eq!(adapter.not(false), true); + + // and + assert_eq!(adapter.and(true, true), true); + assert_eq!(adapter.and(true, false), false); + assert_eq!(adapter.and(false, false), false); + + // or + assert_eq!(adapter.or(true, false), true); + assert_eq!(adapter.or(false, false), false); + + // xor + assert_eq!(adapter.xor(true, false), true); + assert_eq!(adapter.xor(true, true), false); + assert_eq!(adapter.xor(false, false), false); +} +``` + +### 14.6 成果統計 + +**#[allow(dead_code)] 完全削除達成**: +- Phase 95.5: 2箇所(IntegerBoxAdapter, BoolBoxAdapter) +- Phase 97: **0箇所(100%削減達成)** + +**Adapter パターン完成(全6個)**: +1. **Ring0直結型** (1個): ConsoleService +2. **純粋関数型** (3個): StringService, IntegerService, BoolService +3. **downcast型** (2個): ArrayService, MapService + +**テスト結果**: +``` +running 13 tests +test runtime::core_services::tests::test_integer_service_operations ... ok +test runtime::core_services::tests::test_bool_service_operations ... ok +test runtime::plugin_host::tests::test_core_services_all_fields ... ok +test runtime::plugin_host::tests::test_core_services_coverage ... ok + +test result: ok. 13 passed; 0 failed; 0 ignored; 0 measured +``` + +### 14.7 API設計の特徴 + +**IntegerService**: +- saturating演算でオーバーフロー対策 +- div() は Option を返してゼロ除算を安全に処理 + +**BoolService**: +- 標準論理演算(not/and/or/xor) +- 純粋関数として実装(副作用なし) + +### 14.8 Phase 97 完全達成 + +**実装完了項目**: +- ✅ IntegerService trait 定義(add/sub/mul/div) +- ✅ BoolService trait 定義(not/and/or/xor) +- ✅ IntegerBoxAdapter/BoolBoxAdapter unit struct化 +- ✅ #[allow(dead_code)] 完全削除(0箇所) +- ✅ PluginHost 初期化更新 +- ✅ テスト追加(IntegerService/BoolService) +- ✅ 全テストPASS確認 +- ✅ cargo build --release SUCCESS + +**コード簡略化**: +- #[allow(dead_code)]: 2箇所 → **0箇所(完全削除)** +- innerフィールド削除: 2個(Integer/Bool) +- 存在チェックのみのシンプルな初期化 + +**設計確立**: +- 3つのAdapterパターン完成(全6個のService実装完了) +- 純粋関数型の利点: Box状態不要、テスト容易、並列安全 + +### 14.9 次のステップ(Phase 98-99) + +**Phase 98**: 代表パス拡大(5-10箇所) +- VM実行器での CoreServices 使用 +- 実用コードパスでの検証 +- パフォーマンステスト + +**Phase 99**: CoreServices 完全統合 +- 全6個のService実装完了確認 +- ドキュメント完成 +- ベストプラクティス確立 diff --git a/src/runtime/core_services.rs b/src/runtime/core_services.rs index 356cb17c..a90d6d45 100644 --- a/src/runtime/core_services.rs +++ b/src/runtime/core_services.rs @@ -20,13 +20,37 @@ pub trait StringService: Send + Sync { } /// IntegerBox Service trait +/// +/// Phase 97: 純粋関数型(加算・減算・比較など) pub trait IntegerService: Send + Sync { - // Phase 92 以降で実装 + /// 2つの整数を加算 + fn add(&self, a: i64, b: i64) -> i64; + + /// 2つの整数を減算 + fn sub(&self, a: i64, b: i64) -> i64; + + /// 2つの整数を乗算 + fn mul(&self, a: i64, b: i64) -> i64; + + /// 2つの整数を除算(ゼロ除算はNone) + fn div(&self, a: i64, b: i64) -> Option; } /// BoolBox Service trait +/// +/// Phase 97: 純粋関数型(論理演算) pub trait BoolService: Send + Sync { - // Phase 92 以降で実装 + /// 論理NOT + fn not(&self, value: bool) -> bool; + + /// 論理AND + fn and(&self, a: bool, b: bool) -> bool; + + /// 論理OR + fn or(&self, a: bool, b: bool) -> bool; + + /// 論理XOR + fn xor(&self, a: bool, b: bool) -> bool; } /// ArrayBox Service trait @@ -157,40 +181,64 @@ impl StringService for StringBoxAdapter { /// IntegerBox → IntegerService Adapter /// -/// Phase 95.5: inner フィールドは #[allow(dead_code)] のまま保持 -/// Phase 97 で実装予定(純粋関数型として実装) -pub struct IntegerBoxAdapter { - #[allow(dead_code)] - inner: Box, -} +/// Phase 97: 純粋関数型(Box状態不要) +pub struct IntegerBoxAdapter; impl IntegerBoxAdapter { - pub fn new(box_instance: Box) -> Self { - Self { inner: box_instance } + pub fn new() -> Self { + Self } } impl IntegerService for IntegerBoxAdapter { - // Phase 97 で実装予定 + fn add(&self, a: i64, b: i64) -> i64 { + a.saturating_add(b) // オーバーフロー対策 + } + + fn sub(&self, a: i64, b: i64) -> i64 { + a.saturating_sub(b) // アンダーフロー対策 + } + + fn mul(&self, a: i64, b: i64) -> i64 { + a.saturating_mul(b) // オーバーフロー対策 + } + + fn div(&self, a: i64, b: i64) -> Option { + if b == 0 { + None // ゼロ除算 + } else { + Some(a / b) + } + } } /// BoolBox → BoolService Adapter /// -/// Phase 95.5: inner フィールドは #[allow(dead_code)] のまま保持 -/// Phase 97 で実装予定(純粋関数型として実装) -pub struct BoolBoxAdapter { - #[allow(dead_code)] - inner: Box, -} +/// Phase 97: 純粋関数型(Box状態不要) +pub struct BoolBoxAdapter; impl BoolBoxAdapter { - pub fn new(box_instance: Box) -> Self { - Self { inner: box_instance } + pub fn new() -> Self { + Self } } impl BoolService for BoolBoxAdapter { - // Phase 97 で実装予定 + fn not(&self, value: bool) -> bool { + !value + } + + fn and(&self, a: bool, b: bool) -> bool { + a && b + } + + fn or(&self, a: bool, b: bool) -> bool { + a || b + } + + fn xor(&self, a: bool, b: bool) -> bool { + a ^ b + } } /// ArrayBox → ArrayService Adapter @@ -497,4 +545,49 @@ mod tests { let age_int = age.as_any().downcast_ref::().unwrap(); assert_eq!(age_int.value, 25); } + + #[test] + fn test_integer_service_operations() { + let adapter = IntegerBoxAdapter::new(); + + // add + assert_eq!(adapter.add(10, 20), 30); + assert_eq!(adapter.add(i64::MAX, 1), i64::MAX); // saturating + + // sub + assert_eq!(adapter.sub(20, 10), 10); + assert_eq!(adapter.sub(i64::MIN, 1), i64::MIN); // saturating + + // mul + assert_eq!(adapter.mul(5, 6), 30); + assert_eq!(adapter.mul(i64::MAX, 2), i64::MAX); // saturating + + // div + assert_eq!(adapter.div(20, 5), Some(4)); + assert_eq!(adapter.div(10, 3), Some(3)); // 整数除算 + assert_eq!(adapter.div(10, 0), None); // ゼロ除算 + } + + #[test] + fn test_bool_service_operations() { + let adapter = BoolBoxAdapter::new(); + + // not + assert_eq!(adapter.not(true), false); + assert_eq!(adapter.not(false), true); + + // and + assert_eq!(adapter.and(true, true), true); + assert_eq!(adapter.and(true, false), false); + assert_eq!(adapter.and(false, false), false); + + // or + assert_eq!(adapter.or(true, false), true); + assert_eq!(adapter.or(false, false), false); + + // xor + assert_eq!(adapter.xor(true, false), true); + assert_eq!(adapter.xor(true, true), false); + assert_eq!(adapter.xor(false, false), false); + } } diff --git a/src/runtime/plugin_host.rs b/src/runtime/plugin_host.rs index 424bd69a..b2ad101e 100644 --- a/src/runtime/plugin_host.rs +++ b/src/runtime/plugin_host.rs @@ -109,23 +109,23 @@ impl PluginHost { } let string_service = Arc::new(StringBoxAdapter::new()); - // IntegerBox - let integer_box = registry - .create_box("IntegerBox", &[]) - .map_err(|e| CoreInitError::MissingService { + // IntegerBox (Phase 97: 純粋関数化、存在チェックのみ) + if !registry.has_type("IntegerBox") { + return Err(CoreInitError::MissingService { box_id: CoreBoxId::Integer, - message: format!("IntegerBox creation failed: {}", e), - })?; - let integer_service = Arc::new(IntegerBoxAdapter::new(integer_box)); + message: "IntegerBox not found in registry".to_string(), + }); + } + let integer_service = Arc::new(IntegerBoxAdapter::new()); - // BoolBox - let bool_box = registry - .create_box("BoolBox", &[]) - .map_err(|e| CoreInitError::MissingService { + // BoolBox (Phase 97: 純粋関数化、存在チェックのみ) + if !registry.has_type("BoolBox") { + return Err(CoreInitError::MissingService { box_id: CoreBoxId::Bool, - message: format!("BoolBox creation failed: {}", e), - })?; - let bool_service = Arc::new(BoolBoxAdapter::new(bool_box)); + message: "BoolBox not found in registry".to_string(), + }); + } + let bool_service = Arc::new(BoolBoxAdapter::new()); // ArrayBox (Phase 96: downcast パターン、存在チェックのみ) if !registry.has_type("ArrayBox") {