//! Phase 91: CoreServices 定義 //! //! Ring1-Core: core_required Box の Service trait 群。 //! Phase 87 CoreBoxId の core_required (6個) 全てをカバー。 use std::sync::Arc; use crate::runtime::CoreBoxId; use crate::box_trait::NyashBox; /// StringBox Service trait /// /// Phase 95: len のみ実装 pub trait StringService: Send + Sync { fn len(&self, s: &str) -> i64; } /// IntegerBox Service trait pub trait IntegerService: Send + Sync { // Phase 92 以降で実装 } /// BoolBox Service trait pub trait BoolService: Send + Sync { // Phase 92 以降で実装 } /// ArrayBox Service trait pub trait ArrayService: Send + Sync { // Phase 92 以降で実装 } /// MapBox Service trait pub trait MapService: Send + Sync { // Phase 92 以降で実装 } /// ConsoleBox Service trait /// /// Phase 95: println と print のみ実装 pub trait ConsoleService: Send + Sync { fn println(&self, msg: &str); fn print(&self, msg: &str); } /// CoreServices: core_required Box の集合 /// /// Phase 85 設計原則: /// - core_required は必ず全て揃っていなければならない /// - 起動時に全フィールドが初期化されていることを保証 /// /// Phase 87 CoreBoxId との対応: /// - String → string /// - Integer → integer /// - Bool → bool /// - Array → array /// - Map → map /// - Console → console pub struct CoreServices { pub string: Arc, pub integer: Arc, pub bool: Arc, pub array: Arc, pub map: Arc, pub console: Arc, } impl std::fmt::Debug for CoreServices { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("CoreServices") .field("string", &"StringService") .field("integer", &"IntegerService") .field("bool", &"BoolService") .field("array", &"ArrayService") .field("map", &"MapService") .field("console", &"ConsoleService") .finish() } } impl CoreServices { /// Phase 87 CoreBoxId の core_required (6個) を返す /// /// Phase 87 CoreBoxId::is_core_required() と完全一致する。 pub fn required_ids() -> &'static [CoreBoxId] { &[ CoreBoxId::String, CoreBoxId::Integer, CoreBoxId::Bool, CoreBoxId::Array, CoreBoxId::Map, CoreBoxId::Console, ] } /// 全フィールドが初期化されているか検証 /// Phase 92 以降で各 Service の初期化を検証 pub fn ensure_initialized(&self) { // Phase 91 では trait が空なので何もしない // Phase 92 以降で各 Service の初期化を検証 } } // ============================================================================ // Phase 94: Adapter Pattern - Box → Service 変換 // ============================================================================ /// StringBox → StringService Adapter /// /// Phase 95.5: 純粋関数設計 /// - Box を保持せず、純粋関数として実装 /// - len(s) → s.chars().count() (UTF-8 文字数) /// - Phase 96 以降で substring(), concat() など追加予定 pub struct StringBoxAdapter; impl StringBoxAdapter { pub fn new() -> Self { Self } } impl StringService for StringBoxAdapter { fn len(&self, s: &str) -> i64 { // 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, } impl IntegerBoxAdapter { pub fn new(box_instance: Box) -> Self { Self { inner: box_instance } } } impl IntegerService for IntegerBoxAdapter { // Phase 96 以降で実装 } /// BoolBox → BoolService Adapter /// /// Phase 95.5: inner フィールドは #[allow(dead_code)] のまま保持 /// Phase 96 以降で実装時に、Box 状態が必要か純粋関数で足りるか判断 pub struct BoolBoxAdapter { #[allow(dead_code)] inner: Box, } impl BoolBoxAdapter { pub fn new(box_instance: Box) -> Self { Self { inner: box_instance } } } impl BoolService for BoolBoxAdapter { // Phase 96 以降で実装 } /// ArrayBox → ArrayService Adapter /// /// Phase 95.5: inner フィールドは #[allow(dead_code)] のまま保持 /// Phase 96 以降で実装時に、Box 状態が必要か純粋関数で足りるか判断 pub struct ArrayBoxAdapter { #[allow(dead_code)] inner: Box, } impl ArrayBoxAdapter { pub fn new(box_instance: Box) -> Self { Self { inner: box_instance } } } impl ArrayService for ArrayBoxAdapter { // Phase 96 以降で実装 } /// MapBox → MapService Adapter /// /// Phase 95.5: inner フィールドは #[allow(dead_code)] のまま保持 /// Phase 96 以降で実装時に、Box 状態が必要か純粋関数で足りるか判断 pub struct MapBoxAdapter { #[allow(dead_code)] inner: Box, } impl MapBoxAdapter { pub fn new(box_instance: Box) -> Self { Self { inner: box_instance } } } impl MapService for MapBoxAdapter { // Phase 96 以降で実装 } /// ConsoleBox → ConsoleService Adapter /// /// Phase 95.5: Ring0 直結設計 /// - Box を保持せず、Ring0Context に直結 /// - println() → Ring0Context.log.info() /// - print() → Ring0Context.io.stdout_write() pub struct ConsoleBoxAdapter; impl ConsoleBoxAdapter { pub fn new() -> Self { Self } } impl ConsoleService for ConsoleBoxAdapter { fn println(&self, msg: &str) { // 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.5: Ring0Context 経由で stdout 出力(改行なし) use crate::runtime::ring0::get_global_ring0; let ring0 = get_global_ring0(); ring0.io.stdout_write(msg.as_bytes()).ok(); } } #[cfg(test)] mod tests { use super::*; #[test] fn test_required_ids_consistency() { let required = CoreServices::required_ids(); assert_eq!(required.len(), 6); // Phase 87 CoreBoxId::is_core_required() と一致 for id in required { assert!(id.is_core_required()); } // 全ての core_required が含まれているか確認 assert!(required.contains(&CoreBoxId::String)); assert!(required.contains(&CoreBoxId::Integer)); assert!(required.contains(&CoreBoxId::Bool)); assert!(required.contains(&CoreBoxId::Array)); assert!(required.contains(&CoreBoxId::Map)); 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() { // Phase 95.5: Ring0 初期化(安全な初期化) ensure_ring0_initialized(); let adapter = ConsoleBoxAdapter::new(); // Phase 95.5: println を呼び出し(Ring0 経由、panic しないことを確認) adapter.println("Test message from Ring0"); // 実際の出力検証は Phase 96 以降 } #[test] fn test_console_service_print() { // Phase 95.5: Ring0 初期化(安全な初期化) ensure_ring0_initialized(); let adapter = ConsoleBoxAdapter::new(); // Phase 95.5: print を呼び出し(Ring0 経由、panic しないことを確認) adapter.print("No newline"); // 実際の出力検証は Phase 96 以降 } #[test] fn test_string_service_len() { // Phase 95.5: 純粋関数なので Ring0 不要 let adapter = StringBoxAdapter::new(); // Phase 95: len を呼び出し let length = adapter.len("Hello"); assert_eq!(length, 5); // UTF-8 対応確認 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 しないことを確認 } }