115 lines
2.8 KiB
Rust
115 lines
2.8 KiB
Rust
|
|
//! Phase 88: Ring0Context - OS API 抽象化レイヤー
|
|||
|
|
//!
|
|||
|
|
//! Ring0 は Box を知らない、Nyash を知らない純粋な OS API 層。
|
|||
|
|
|
|||
|
|
mod errors;
|
|||
|
|
mod std_impls;
|
|||
|
|
mod traits;
|
|||
|
|
|
|||
|
|
pub use errors::{IoError, TimeError};
|
|||
|
|
pub use std_impls::{NoopMem, StdIo, StdLog, StdTime};
|
|||
|
|
pub use traits::{IoApi, LogApi, LogLevel, MemApi, MemStats, TimeApi};
|
|||
|
|
|
|||
|
|
use std::sync::{Arc, OnceLock};
|
|||
|
|
|
|||
|
|
/// Phase 88: Ring0 コンテキスト
|
|||
|
|
///
|
|||
|
|
/// OS API レイヤーを trait で抽象化し、1つの構造体に束ねる。
|
|||
|
|
pub struct Ring0Context {
|
|||
|
|
pub mem: Arc<dyn MemApi>,
|
|||
|
|
pub io: Arc<dyn IoApi>,
|
|||
|
|
pub time: Arc<dyn TimeApi>,
|
|||
|
|
pub log: Arc<dyn LogApi>,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
impl Ring0Context {
|
|||
|
|
/// 新規 Ring0Context を作成
|
|||
|
|
pub fn new(
|
|||
|
|
mem: Arc<dyn MemApi>,
|
|||
|
|
io: Arc<dyn IoApi>,
|
|||
|
|
time: Arc<dyn TimeApi>,
|
|||
|
|
log: Arc<dyn LogApi>,
|
|||
|
|
) -> Self {
|
|||
|
|
Self { mem, io, time, log }
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
impl std::fmt::Debug for Ring0Context {
|
|||
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|||
|
|
f.debug_struct("Ring0Context")
|
|||
|
|
.field("mem", &"<dyn MemApi>")
|
|||
|
|
.field("io", &"<dyn IoApi>")
|
|||
|
|
.field("time", &"<dyn TimeApi>")
|
|||
|
|
.field("log", &"<dyn LogApi>")
|
|||
|
|
.finish()
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// デフォルト Ring0Context を作成(std ベース)
|
|||
|
|
pub fn default_ring0() -> Ring0Context {
|
|||
|
|
Ring0Context {
|
|||
|
|
mem: Arc::new(NoopMem),
|
|||
|
|
io: Arc::new(StdIo),
|
|||
|
|
time: Arc::new(StdTime),
|
|||
|
|
log: Arc::new(StdLog),
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ===== グローバル Ring0Context =====
|
|||
|
|
|
|||
|
|
pub static GLOBAL_RING0: OnceLock<Arc<Ring0Context>> = OnceLock::new();
|
|||
|
|
|
|||
|
|
/// グローバル Ring0Context を初期化
|
|||
|
|
pub fn init_global_ring0(ctx: Ring0Context) {
|
|||
|
|
GLOBAL_RING0
|
|||
|
|
.set(Arc::new(ctx))
|
|||
|
|
.expect("[Phase 88] Ring0Context already initialized");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// グローバル Ring0Context を取得
|
|||
|
|
pub fn get_global_ring0() -> Arc<Ring0Context> {
|
|||
|
|
GLOBAL_RING0
|
|||
|
|
.get()
|
|||
|
|
.expect("[Phase 88] Ring0Context not initialized")
|
|||
|
|
.clone()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ===== テスト =====
|
|||
|
|
|
|||
|
|
#[cfg(test)]
|
|||
|
|
mod tests {
|
|||
|
|
use super::*;
|
|||
|
|
|
|||
|
|
#[test]
|
|||
|
|
fn test_ring0_context_creation() {
|
|||
|
|
let ring0 = default_ring0();
|
|||
|
|
ring0.log.info("test message");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#[test]
|
|||
|
|
fn test_io_api() {
|
|||
|
|
let ring0 = default_ring0();
|
|||
|
|
let result = ring0.io.stdout_write(b"test\n");
|
|||
|
|
assert!(result.is_ok());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#[test]
|
|||
|
|
fn test_time_api() {
|
|||
|
|
let ring0 = default_ring0();
|
|||
|
|
let now = ring0.time.now();
|
|||
|
|
assert!(now.is_ok());
|
|||
|
|
|
|||
|
|
let instant = ring0.time.monotonic_now();
|
|||
|
|
assert!(instant.is_ok());
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#[test]
|
|||
|
|
fn test_log_levels() {
|
|||
|
|
let ring0 = default_ring0();
|
|||
|
|
ring0.log.debug("debug message");
|
|||
|
|
ring0.log.info("info message");
|
|||
|
|
ring0.log.warn("warn message");
|
|||
|
|
ring0.log.error("error message");
|
|||
|
|
}
|
|||
|
|
}
|