2025-12-03 07:43:08 +09:00
|
|
|
|
//! Phase 91: CoreServices 定義
|
|
|
|
|
|
//!
|
|
|
|
|
|
//! Ring1-Core: core_required Box の Service trait 群。
|
|
|
|
|
|
//! Phase 87 CoreBoxId の core_required (6個) 全てをカバー。
|
|
|
|
|
|
|
|
|
|
|
|
use std::sync::Arc;
|
2025-12-03 07:57:21 +09:00
|
|
|
|
use crate::runtime::CoreBoxId;
|
2025-12-03 09:14:49 +09:00
|
|
|
|
use crate::box_trait::NyashBox;
|
2025-12-03 07:43:08 +09:00
|
|
|
|
|
|
|
|
|
|
/// StringBox Service trait
|
2025-12-03 09:57:38 +09:00
|
|
|
|
///
|
|
|
|
|
|
/// Phase 95: len のみ実装
|
2025-12-03 07:43:08 +09:00
|
|
|
|
pub trait StringService: Send + Sync {
|
2025-12-03 09:57:38 +09:00
|
|
|
|
fn len(&self, s: &str) -> i64;
|
2025-12-03 07:43:08 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 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
|
2025-12-03 09:57:38 +09:00
|
|
|
|
///
|
|
|
|
|
|
/// Phase 95: println と print のみ実装
|
2025-12-03 07:43:08 +09:00
|
|
|
|
pub trait ConsoleService: Send + Sync {
|
2025-12-03 09:57:38 +09:00
|
|
|
|
fn println(&self, msg: &str);
|
|
|
|
|
|
fn print(&self, msg: &str);
|
2025-12-03 07:43:08 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// 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<dyn StringService>,
|
|
|
|
|
|
pub integer: Arc<dyn IntegerService>,
|
|
|
|
|
|
pub bool: Arc<dyn BoolService>,
|
|
|
|
|
|
pub array: Arc<dyn ArrayService>,
|
|
|
|
|
|
pub map: Arc<dyn MapService>,
|
|
|
|
|
|
pub console: Arc<dyn ConsoleService>,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-03 09:57:38 +09:00
|
|
|
|
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()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-03 07:43:08 +09:00
|
|
|
|
impl CoreServices {
|
2025-12-03 07:57:21 +09:00
|
|
|
|
/// 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,
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-03 07:43:08 +09:00
|
|
|
|
/// 全フィールドが初期化されているか検証
|
|
|
|
|
|
/// Phase 92 以降で各 Service の初期化を検証
|
|
|
|
|
|
pub fn ensure_initialized(&self) {
|
|
|
|
|
|
// Phase 91 では trait が空なので何もしない
|
|
|
|
|
|
// Phase 92 以降で各 Service の初期化を検証
|
|
|
|
|
|
}
|
2025-12-03 08:42:45 +09:00
|
|
|
|
|
2025-12-03 09:14:49 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
// Phase 94: Adapter Pattern - Box → Service 変換
|
|
|
|
|
|
// ============================================================================
|
|
|
|
|
|
|
|
|
|
|
|
/// StringBox → StringService Adapter
|
2025-12-03 10:15:23 +09:00
|
|
|
|
///
|
|
|
|
|
|
/// Phase 95.5: 純粋関数設計
|
|
|
|
|
|
/// - Box を保持せず、純粋関数として実装
|
|
|
|
|
|
/// - len(s) → s.chars().count() (UTF-8 文字数)
|
|
|
|
|
|
/// - Phase 96 以降で substring(), concat() など追加予定
|
|
|
|
|
|
pub struct StringBoxAdapter;
|
2025-12-03 09:14:49 +09:00
|
|
|
|
|
|
|
|
|
|
impl StringBoxAdapter {
|
2025-12-03 10:15:23 +09:00
|
|
|
|
pub fn new() -> Self {
|
|
|
|
|
|
Self
|
2025-12-03 09:14:49 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl StringService for StringBoxAdapter {
|
2025-12-03 09:57:38 +09:00
|
|
|
|
fn len(&self, s: &str) -> i64 {
|
2025-12-03 10:15:23 +09:00
|
|
|
|
// Phase 95.5: 文字列長を返す(UTF-8 バイト数ではなく文字数)
|
2025-12-03 09:57:38 +09:00
|
|
|
|
s.chars().count() as i64
|
|
|
|
|
|
}
|
2025-12-03 09:14:49 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// IntegerBox → IntegerService Adapter
|
2025-12-03 10:15:23 +09:00
|
|
|
|
///
|
|
|
|
|
|
/// Phase 95.5: inner フィールドは #[allow(dead_code)] のまま保持
|
|
|
|
|
|
/// Phase 96 以降で実装時に、Box 状態が必要か純粋関数で足りるか判断
|
2025-12-03 09:14:49 +09:00
|
|
|
|
pub struct IntegerBoxAdapter {
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
|
|
inner: Box<dyn NyashBox>,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl IntegerBoxAdapter {
|
|
|
|
|
|
pub fn new(box_instance: Box<dyn NyashBox>) -> Self {
|
|
|
|
|
|
Self { inner: box_instance }
|
2025-12-03 08:42:45 +09:00
|
|
|
|
}
|
2025-12-03 07:43:08 +09:00
|
|
|
|
}
|
2025-12-03 07:57:21 +09:00
|
|
|
|
|
2025-12-03 09:14:49 +09:00
|
|
|
|
impl IntegerService for IntegerBoxAdapter {
|
2025-12-03 10:15:23 +09:00
|
|
|
|
// Phase 96 以降で実装
|
2025-12-03 09:14:49 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// BoolBox → BoolService Adapter
|
2025-12-03 10:15:23 +09:00
|
|
|
|
///
|
|
|
|
|
|
/// Phase 95.5: inner フィールドは #[allow(dead_code)] のまま保持
|
|
|
|
|
|
/// Phase 96 以降で実装時に、Box 状態が必要か純粋関数で足りるか判断
|
2025-12-03 09:14:49 +09:00
|
|
|
|
pub struct BoolBoxAdapter {
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
|
|
inner: Box<dyn NyashBox>,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl BoolBoxAdapter {
|
|
|
|
|
|
pub fn new(box_instance: Box<dyn NyashBox>) -> Self {
|
|
|
|
|
|
Self { inner: box_instance }
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl BoolService for BoolBoxAdapter {
|
2025-12-03 10:15:23 +09:00
|
|
|
|
// Phase 96 以降で実装
|
2025-12-03 09:14:49 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// ArrayBox → ArrayService Adapter
|
2025-12-03 10:15:23 +09:00
|
|
|
|
///
|
|
|
|
|
|
/// Phase 95.5: inner フィールドは #[allow(dead_code)] のまま保持
|
|
|
|
|
|
/// Phase 96 以降で実装時に、Box 状態が必要か純粋関数で足りるか判断
|
2025-12-03 09:14:49 +09:00
|
|
|
|
pub struct ArrayBoxAdapter {
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
|
|
inner: Box<dyn NyashBox>,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl ArrayBoxAdapter {
|
|
|
|
|
|
pub fn new(box_instance: Box<dyn NyashBox>) -> Self {
|
|
|
|
|
|
Self { inner: box_instance }
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl ArrayService for ArrayBoxAdapter {
|
2025-12-03 10:15:23 +09:00
|
|
|
|
// Phase 96 以降で実装
|
2025-12-03 09:14:49 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// MapBox → MapService Adapter
|
2025-12-03 10:15:23 +09:00
|
|
|
|
///
|
|
|
|
|
|
/// Phase 95.5: inner フィールドは #[allow(dead_code)] のまま保持
|
|
|
|
|
|
/// Phase 96 以降で実装時に、Box 状態が必要か純粋関数で足りるか判断
|
2025-12-03 09:14:49 +09:00
|
|
|
|
pub struct MapBoxAdapter {
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
|
|
inner: Box<dyn NyashBox>,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl MapBoxAdapter {
|
|
|
|
|
|
pub fn new(box_instance: Box<dyn NyashBox>) -> Self {
|
|
|
|
|
|
Self { inner: box_instance }
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl MapService for MapBoxAdapter {
|
2025-12-03 10:15:23 +09:00
|
|
|
|
// Phase 96 以降で実装
|
2025-12-03 09:14:49 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// ConsoleBox → ConsoleService Adapter
|
2025-12-03 10:15:23 +09:00
|
|
|
|
///
|
|
|
|
|
|
/// Phase 95.5: Ring0 直結設計
|
|
|
|
|
|
/// - Box を保持せず、Ring0Context に直結
|
|
|
|
|
|
/// - println() → Ring0Context.log.info()
|
|
|
|
|
|
/// - print() → Ring0Context.io.stdout_write()
|
|
|
|
|
|
pub struct ConsoleBoxAdapter;
|
2025-12-03 09:14:49 +09:00
|
|
|
|
|
|
|
|
|
|
impl ConsoleBoxAdapter {
|
2025-12-03 10:15:23 +09:00
|
|
|
|
pub fn new() -> Self {
|
|
|
|
|
|
Self
|
2025-12-03 09:14:49 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl ConsoleService for ConsoleBoxAdapter {
|
2025-12-03 09:57:38 +09:00
|
|
|
|
fn println(&self, msg: &str) {
|
2025-12-03 10:15:23 +09:00
|
|
|
|
// Phase 95.5: Ring0Context 経由でログ出力(自動改行)
|
|
|
|
|
|
use crate::runtime::ring0::get_global_ring0;
|
|
|
|
|
|
let ring0 = get_global_ring0();
|
|
|
|
|
|
ring0.log.info(msg);
|
2025-12-03 09:57:38 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn print(&self, msg: &str) {
|
2025-12-03 10:15:23 +09:00
|
|
|
|
// 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();
|
2025-12-03 09:57:38 +09:00
|
|
|
|
}
|
2025-12-03 09:14:49 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-03 07:57:21 +09:00
|
|
|
|
#[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));
|
|
|
|
|
|
}
|
2025-12-03 09:57:38 +09:00
|
|
|
|
|
2025-12-03 10:15:23 +09:00
|
|
|
|
// 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();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-03 09:57:38 +09:00
|
|
|
|
#[test]
|
|
|
|
|
|
fn test_console_service_println() {
|
2025-12-03 10:15:23 +09:00
|
|
|
|
// Phase 95.5: Ring0 初期化(安全な初期化)
|
|
|
|
|
|
ensure_ring0_initialized();
|
2025-12-03 09:57:38 +09:00
|
|
|
|
|
2025-12-03 10:15:23 +09:00
|
|
|
|
let adapter = ConsoleBoxAdapter::new();
|
2025-12-03 09:57:38 +09:00
|
|
|
|
|
2025-12-03 10:15:23 +09:00
|
|
|
|
// Phase 95.5: println を呼び出し(Ring0 経由、panic しないことを確認)
|
|
|
|
|
|
adapter.println("Test message from Ring0");
|
2025-12-03 09:57:38 +09:00
|
|
|
|
// 実際の出力検証は Phase 96 以降
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
|
fn test_console_service_print() {
|
2025-12-03 10:15:23 +09:00
|
|
|
|
// Phase 95.5: Ring0 初期化(安全な初期化)
|
|
|
|
|
|
ensure_ring0_initialized();
|
2025-12-03 09:57:38 +09:00
|
|
|
|
|
2025-12-03 10:15:23 +09:00
|
|
|
|
let adapter = ConsoleBoxAdapter::new();
|
2025-12-03 09:57:38 +09:00
|
|
|
|
|
2025-12-03 10:15:23 +09:00
|
|
|
|
// Phase 95.5: print を呼び出し(Ring0 経由、panic しないことを確認)
|
|
|
|
|
|
adapter.print("No newline");
|
2025-12-03 09:57:38 +09:00
|
|
|
|
// 実際の出力検証は Phase 96 以降
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
|
fn test_string_service_len() {
|
2025-12-03 10:15:23 +09:00
|
|
|
|
// Phase 95.5: 純粋関数なので Ring0 不要
|
|
|
|
|
|
let adapter = StringBoxAdapter::new();
|
2025-12-03 09:57:38 +09:00
|
|
|
|
|
|
|
|
|
|
// 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)
|
|
|
|
|
|
}
|
2025-12-03 10:15:23 +09:00
|
|
|
|
|
|
|
|
|
|
#[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 しないことを確認
|
|
|
|
|
|
}
|
2025-12-03 07:57:21 +09:00
|
|
|
|
}
|