feat(runtime): Phase 97 IntegerService/BoolService 完全実装 - #[allow(dead_code)] 100%根絶達成

## Phase 97 完了項目
-  IntegerService trait & Adapter実装(add/sub/mul/div, saturating算術)
-  BoolService trait & Adapter実装(not/and/or/xor)
-  #[allow(dead_code)] 6箇所→0箇所(100%削減完了)
-  全13テストPASS(IntegerService 2テスト、BoolService 1テスト追加)

## 技術的成果
**3つのAdapterパターン確立完了**:
1. Ring0直結型: ConsoleService(OS API thin wrapper)
2. 純粋関数型: StringService, IntegerService, BoolService(stateless)
3. downcast型: ArrayService, MapService(複数インスタンス対応)

**CoreServices完全実装**:
- core_required 6個すべて実装完了
- String, Integer, Bool, Array, Map, Console

**オーバーフロー対策**:
- saturating_add/sub/mul でi64オーバーフロー安全
- div はゼロ除算でOption::None返却

## 実装詳細
- src/runtime/core_services.rs: +74行(IntegerService/BoolService traits & impls)
- src/runtime/plugin_host.rs: +2行(Integer/Bool初期化チェック)
- docs/development/current/main/core_boxes_design.md: +256行(Section 14追加)

## Phase 85-97 総括
- Phase 85: 構造設計(CoreServices/PluginHost skeleton)
- Phase 91-94: PluginHost実装 & 箱化モジュール化
- Phase 95.5: StringService/ConsoleService(Ring0直結型・純粋関数型)
- Phase 96: ArrayService/MapService(downcast型)
- Phase 96.5: コード整理(use文統合、コメント更新)
- Phase 97: IntegerService/BoolService(純粋関数型)  完了

次: Phase 98(代表パス拡張 5-10箇所)

🎊 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-12-03 10:41:16 +09:00
parent 8995fd151d
commit 04dceb6bc0
3 changed files with 383 additions and 34 deletions

View File

@ -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<i64>;
}
/// 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<dyn NyashBox>,
}
/// Phase 97: 純粋関数型Box状態不要
pub struct IntegerBoxAdapter;
impl IntegerBoxAdapter {
pub fn new(box_instance: Box<dyn NyashBox>) -> 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<i64> {
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<dyn NyashBox>,
}
/// Phase 97: 純粋関数型Box状態不要
pub struct BoolBoxAdapter;
impl BoolBoxAdapter {
pub fn new(box_instance: Box<dyn NyashBox>) -> 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::<IntegerBox>().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);
}
}

View File

@ -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") {