🚀 feat: BoxBase+BoxCore革命 Phase4進捗 - 12+Box型統一完了

 完了したBox型統一アーキテクチャ移行
- MathBox関連: MathBox, FloatBox, RangeBox
- TimeBox関連: TimeBox, DateTimeBox, TimerBox
- DebugBox, RandomBox
- StringBox, IntegerBox, BoolBox (個別ファイル版)
- ArrayBox, ConsoleBox
- box_trait.rs内: StringBox, IntegerBox, BoolBox, VoidBox等

🎯 大幅な進捗達成
- unsafe ID生成 → BoxBase::new()安全化
- コンパイルエラー: 106 → 97に減少
- 統一インターフェース確立でCharmFlow互換性問題完全回避

🔧 革命的変更パターン確立
1. base: BoxBase導入
2. impl BoxCore with box_id()/fmt_box()
3. NyashBoxからbox_id()削除
4. Display::fmt() → fmt_box()委譲

Phase 4E: 残りBox型の統一化継続中

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Moe Charm
2025-08-11 11:25:17 +09:00
parent 73a12dfb56
commit edcf4bf0a7
11 changed files with 260 additions and 1512 deletions

View File

@ -616,6 +616,16 @@ impl ResultBox {
} }
} }
impl BoxCore for ResultBox {
fn box_id(&self) -> u64 {
self.base.id
}
fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.to_string_box().value)
}
}
impl NyashBox for ResultBox { impl NyashBox for ResultBox {
fn to_string_box(&self) -> StringBox { fn to_string_box(&self) -> StringBox {
if self.is_success { if self.is_success {
@ -682,15 +692,11 @@ impl NyashBox for ResultBox {
fn as_any(&self) -> &dyn Any { fn as_any(&self) -> &dyn Any {
self self
} }
fn box_id(&self) -> u64 {
self.id
}
} }
impl Display for ResultBox { impl Display for ResultBox {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.to_string_box().value) self.fmt_box(f)
} }
} }
@ -798,15 +804,21 @@ impl NyashBox for FutureBox {
fn as_any(&self) -> &dyn Any { fn as_any(&self) -> &dyn Any {
self self
} }
}
impl BoxCore for FutureBox {
fn box_id(&self) -> u64 { fn box_id(&self) -> u64 {
self.id self.base.id
}
fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.to_string_box().value)
} }
} }
impl Display for FutureBox { impl Display for FutureBox {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.to_string_box().value) self.fmt_box(f)
} }
} }
@ -816,7 +828,7 @@ impl Display for FutureBox {
pub struct AddBox { pub struct AddBox {
pub left: Box<dyn NyashBox>, pub left: Box<dyn NyashBox>,
pub right: Box<dyn NyashBox>, pub right: Box<dyn NyashBox>,
id: u64, base: BoxBase,
} }
impl AddBox { impl AddBox {
@ -824,7 +836,7 @@ impl AddBox {
Self { Self {
left, left,
right, right,
id: next_box_id() base: BoxBase::new(),
} }
} }
@ -911,9 +923,21 @@ impl NyashBox for AddBox {
fn as_any(&self) -> &dyn Any { fn as_any(&self) -> &dyn Any {
self self
} }
}
impl BoxCore for AddBox {
fn box_id(&self) -> u64 { fn box_id(&self) -> u64 {
self.id self.base.id
}
fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "({} + {})", self.left.to_string_box().value, self.right.to_string_box().value)
}
}
impl Display for AddBox {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.fmt_box(f)
} }
} }

View File

@ -2,40 +2,31 @@
// Nyashの箱システムによる配列・リスト操作を提供します。 // Nyashの箱システムによる配列・リスト操作を提供します。
// Arc<Mutex>パターンで内部可変性を実現 // Arc<Mutex>パターンで内部可変性を実現
use crate::box_trait::{NyashBox, StringBox, BoolBox, IntegerBox}; use crate::box_trait::{NyashBox, StringBox, BoolBox, IntegerBox, BoxCore, BoxBase};
use std::any::Any; use std::any::Any;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::fmt::Display;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ArrayBox { pub struct ArrayBox {
pub items: Arc<Mutex<Vec<Box<dyn NyashBox>>>>, pub items: Arc<Mutex<Vec<Box<dyn NyashBox>>>>,
id: u64, base: BoxBase,
} }
impl ArrayBox { impl ArrayBox {
/// 新しいArrayBoxを作成 /// 新しいArrayBoxを作成
pub fn new() -> Self { pub fn new() -> Self {
static mut COUNTER: u64 = 0;
let id = unsafe {
COUNTER += 1;
COUNTER
};
ArrayBox { ArrayBox {
items: Arc::new(Mutex::new(Vec::new())), items: Arc::new(Mutex::new(Vec::new())),
id, base: BoxBase::new(),
} }
} }
/// 要素を持つArrayBoxを作成 /// 要素を持つArrayBoxを作成
pub fn new_with_elements(elements: Vec<Box<dyn NyashBox>>) -> Self { pub fn new_with_elements(elements: Vec<Box<dyn NyashBox>>) -> Self {
static mut COUNTER: u64 = 0;
let id = unsafe {
COUNTER += 1;
COUNTER
};
ArrayBox { ArrayBox {
items: Arc::new(Mutex::new(elements)), items: Arc::new(Mutex::new(elements)),
id, base: BoxBase::new(),
} }
} }
@ -146,6 +137,26 @@ impl ArrayBox {
} }
} }
impl BoxCore for ArrayBox {
fn box_id(&self) -> u64 {
self.base.id
}
fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let items = self.items.lock().unwrap();
let strings: Vec<String> = items.iter()
.map(|item| item.to_string_box().value)
.collect();
write!(f, "[{}]", strings.join(", "))
}
}
impl Display for ArrayBox {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.fmt_box(f)
}
}
impl NyashBox for ArrayBox { impl NyashBox for ArrayBox {
fn clone_box(&self) -> Box<dyn NyashBox> { fn clone_box(&self) -> Box<dyn NyashBox> {
Box::new(self.clone()) Box::new(self.clone())
@ -167,9 +178,6 @@ impl NyashBox for ArrayBox {
"ArrayBox" "ArrayBox"
} }
fn box_id(&self) -> u64 {
self.id
}
fn equals(&self, other: &dyn NyashBox) -> BoolBox { fn equals(&self, other: &dyn NyashBox) -> BoolBox {
if let Some(other_array) = other.as_any().downcast_ref::<ArrayBox>() { if let Some(other_array) = other.as_any().downcast_ref::<ArrayBox>() {

View File

@ -38,7 +38,7 @@
* - `a or b` - OR演算子 * - `a or b` - OR演算子
*/ */
use crate::box_trait::NyashBox; use crate::box_trait::{NyashBox, BoxCore, BoxBase};
use std::any::Any; use std::any::Any;
use std::fmt::Display; use std::fmt::Display;
@ -46,18 +46,15 @@ use std::fmt::Display;
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub struct BoolBox { pub struct BoolBox {
pub value: bool, pub value: bool,
id: u64, base: BoxBase,
} }
impl BoolBox { impl BoolBox {
pub fn new(value: bool) -> Self { pub fn new(value: bool) -> Self {
static mut COUNTER: u64 = 0; Self {
let id = unsafe { value,
COUNTER += 1; base: BoxBase::new(),
COUNTER }
};
Self { value, id }
} }
pub fn true_box() -> Self { pub fn true_box() -> Self {
@ -94,13 +91,20 @@ impl NyashBox for BoolBox {
self self
} }
}
impl BoxCore for BoolBox {
fn box_id(&self) -> u64 { fn box_id(&self) -> u64 {
self.id self.base.id
}
fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", if self.value { "true" } else { "false" })
} }
} }
impl Display for BoolBox { impl Display for BoolBox {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", if self.value { "true" } else { "false" }) self.fmt_box(f)
} }
} }

View File

@ -45,7 +45,7 @@
* ``` * ```
*/ */
use crate::box_trait::{NyashBox, StringBox, BoolBox}; use crate::box_trait::{NyashBox, StringBox, BoolBox, BoxCore, BoxBase};
use std::any::Any; use std::any::Any;
use std::fmt::Display; use std::fmt::Display;
@ -53,18 +53,13 @@ use std::fmt::Display;
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ConsoleBox { pub struct ConsoleBox {
id: u64, base: BoxBase,
} }
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
impl ConsoleBox { impl ConsoleBox {
pub fn new() -> Self { pub fn new() -> Self {
static mut COUNTER: u64 = 0; Self { base: BoxBase::new() }
let id = unsafe {
COUNTER += 1;
COUNTER
};
Self { id }
} }
/// Log messages to browser console /// Log messages to browser console
@ -88,6 +83,17 @@ impl ConsoleBox {
} }
} }
#[cfg(target_arch = "wasm32")]
impl BoxCore for ConsoleBox {
fn box_id(&self) -> u64 {
self.base.id
}
fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "[ConsoleBox - Browser Console Interface]")
}
}
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
impl NyashBox for ConsoleBox { impl NyashBox for ConsoleBox {
fn to_string_box(&self) -> StringBox { fn to_string_box(&self) -> StringBox {
@ -109,28 +115,19 @@ impl NyashBox for ConsoleBox {
fn as_any(&self) -> &dyn Any { fn as_any(&self) -> &dyn Any {
self self
} }
fn box_id(&self) -> u64 {
self.id
}
} }
// Non-WASM版 - モックアップ実装 // Non-WASM版 - モックアップ実装
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct ConsoleBox { pub struct ConsoleBox {
id: u64, base: BoxBase,
} }
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
impl ConsoleBox { impl ConsoleBox {
pub fn new() -> Self { pub fn new() -> Self {
static mut COUNTER: u64 = 0; Self { base: BoxBase::new() }
let id = unsafe {
COUNTER += 1;
COUNTER
};
Self { id }
} }
/// Mock log method for non-WASM environments /// Mock log method for non-WASM environments
@ -151,6 +148,17 @@ impl ConsoleBox {
} }
} }
#[cfg(not(target_arch = "wasm32"))]
impl BoxCore for ConsoleBox {
fn box_id(&self) -> u64 {
self.base.id
}
fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "[ConsoleBox - Mock Implementation]")
}
}
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
impl NyashBox for ConsoleBox { impl NyashBox for ConsoleBox {
fn to_string_box(&self) -> StringBox { fn to_string_box(&self) -> StringBox {
@ -172,10 +180,6 @@ impl NyashBox for ConsoleBox {
fn as_any(&self) -> &dyn Any { fn as_any(&self) -> &dyn Any {
self self
} }
fn box_id(&self) -> u64 {
self.id
}
} }
@ -183,13 +187,13 @@ impl NyashBox for ConsoleBox {
#[cfg(target_arch = "wasm32")] #[cfg(target_arch = "wasm32")]
impl Display for ConsoleBox { impl Display for ConsoleBox {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "[ConsoleBox - Browser Console Interface]") self.fmt_box(f)
} }
} }
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
impl Display for ConsoleBox { impl Display for ConsoleBox {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "[ConsoleBox - Mock Implementation]") self.fmt_box(f)
} }
} }

View File

@ -102,18 +102,18 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use chrono::Local; use chrono::Local;
use crate::box_trait::{NyashBox, StringBox, BoolBox, VoidBox}; use crate::box_trait::{BoxCore, BoxBase, next_box_id, NyashBox, StringBox, BoolBox, VoidBox};
use crate::interpreter::RuntimeError; use crate::interpreter::RuntimeError;
use crate::instance::InstanceBox; use crate::instance::InstanceBox;
use std::any::Any; use std::any::Any;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct DebugBox { pub struct DebugBox {
base: BoxBase,
tracking_enabled: Arc<Mutex<bool>>, tracking_enabled: Arc<Mutex<bool>>,
tracked_boxes: Arc<Mutex<HashMap<String, TrackedBoxInfo>>>, tracked_boxes: Arc<Mutex<HashMap<String, TrackedBoxInfo>>>,
breakpoints: Arc<Mutex<Vec<String>>>, breakpoints: Arc<Mutex<Vec<String>>>,
call_stack: Arc<Mutex<Vec<CallInfo>>>, call_stack: Arc<Mutex<Vec<CallInfo>>>,
id: u64,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -133,18 +133,12 @@ struct CallInfo {
impl DebugBox { impl DebugBox {
pub fn new() -> Self { pub fn new() -> Self {
static mut COUNTER: u64 = 0;
let id = unsafe {
COUNTER += 1;
COUNTER
};
DebugBox { DebugBox {
base: BoxBase::new(),
tracking_enabled: Arc::new(Mutex::new(false)), tracking_enabled: Arc::new(Mutex::new(false)),
tracked_boxes: Arc::new(Mutex::new(HashMap::new())), tracked_boxes: Arc::new(Mutex::new(HashMap::new())),
breakpoints: Arc::new(Mutex::new(Vec::new())), breakpoints: Arc::new(Mutex::new(Vec::new())),
call_stack: Arc::new(Mutex::new(Vec::new())), call_stack: Arc::new(Mutex::new(Vec::new())),
id,
} }
} }
@ -314,6 +308,25 @@ impl DebugBox {
} }
} }
// Implement BoxCore trait for DebugBox
impl BoxCore for DebugBox {
fn box_id(&self) -> u64 {
self.base.id
}
fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let tracked = self.tracked_boxes.lock().unwrap();
write!(f, "DebugBox[{} tracked]", tracked.len())
}
}
// Implement Display trait using BoxCore
impl std::fmt::Display for DebugBox {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
self.fmt_box(f)
}
}
// Implement NyashBox trait for DebugBox // Implement NyashBox trait for DebugBox
impl NyashBox for DebugBox { impl NyashBox for DebugBox {
fn to_string_box(&self) -> StringBox { fn to_string_box(&self) -> StringBox {
@ -323,7 +336,7 @@ impl NyashBox for DebugBox {
fn equals(&self, other: &dyn NyashBox) -> BoolBox { fn equals(&self, other: &dyn NyashBox) -> BoolBox {
if let Some(other_debug) = other.as_any().downcast_ref::<DebugBox>() { if let Some(other_debug) = other.as_any().downcast_ref::<DebugBox>() {
BoolBox::new(self.id == other_debug.id) BoolBox::new(self.base.id == other_debug.base.id)
} else { } else {
BoolBox::new(false) BoolBox::new(false)
} }
@ -341,7 +354,4 @@ impl NyashBox for DebugBox {
self self
} }
fn box_id(&self) -> u64 {
self.id
}
} }

View File

@ -37,7 +37,7 @@
* - 小数点以下は切り捨て(整数除算) * - 小数点以下は切り捨て(整数除算)
*/ */
use crate::box_trait::NyashBox; use crate::box_trait::{NyashBox, BoxCore, BoxBase};
use std::any::Any; use std::any::Any;
use std::fmt::Display; use std::fmt::Display;
@ -45,18 +45,15 @@ use std::fmt::Display;
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub struct IntegerBox { pub struct IntegerBox {
pub value: i64, pub value: i64,
id: u64, base: BoxBase,
} }
impl IntegerBox { impl IntegerBox {
pub fn new(value: i64) -> Self { pub fn new(value: i64) -> Self {
static mut COUNTER: u64 = 0; Self {
let id = unsafe { value,
COUNTER += 1; base: BoxBase::new(),
COUNTER }
};
Self { value, id }
} }
pub fn zero() -> Self { pub fn zero() -> Self {
@ -90,13 +87,20 @@ impl NyashBox for IntegerBox {
self self
} }
}
impl BoxCore for IntegerBox {
fn box_id(&self) -> u64 { fn box_id(&self) -> u64 {
self.id self.base.id
}
fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.value)
} }
} }
impl Display for IntegerBox { impl Display for IntegerBox {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.value) self.fmt_box(f)
} }
} }

View File

@ -56,25 +56,21 @@
* - 整数演算は自動でFloatBoxに変換される場合あり * - 整数演算は自動でFloatBoxに変換される場合あり
*/ */
use crate::box_trait::{NyashBox, StringBox, IntegerBox, BoolBox}; use crate::box_trait::{NyashBox, StringBox, IntegerBox, BoolBox, BoxCore, BoxBase, next_box_id};
use std::fmt::{Debug, Display}; use std::fmt::{Debug, Display};
use std::any::Any; use std::any::Any;
/// 数学演算を提供するBox /// 数学演算を提供するBox
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct MathBox { pub struct MathBox {
id: u64, base: BoxBase,
} }
impl MathBox { impl MathBox {
pub fn new() -> Self { pub fn new() -> Self {
static mut COUNTER: u64 = 0; Self {
let id = unsafe { base: BoxBase::new()
COUNTER += 1; }
COUNTER
};
Self { id }
} }
/// 絶対値を計算 /// 絶対値を計算
@ -286,6 +282,16 @@ impl MathBox {
} }
} }
impl BoxCore for MathBox {
fn box_id(&self) -> u64 {
self.base.id
}
fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "MathBox()")
}
}
impl NyashBox for MathBox { impl NyashBox for MathBox {
fn type_name(&self) -> &'static str { fn type_name(&self) -> &'static str {
"MathBox" "MathBox"
@ -301,7 +307,7 @@ impl NyashBox for MathBox {
fn equals(&self, other: &dyn NyashBox) -> BoolBox { fn equals(&self, other: &dyn NyashBox) -> BoolBox {
if let Some(other_math) = other.as_any().downcast_ref::<MathBox>() { if let Some(other_math) = other.as_any().downcast_ref::<MathBox>() {
BoolBox::new(self.id == other_math.id) BoolBox::new(self.box_id() == other_math.box_id())
} else { } else {
BoolBox::new(false) BoolBox::new(false)
} }
@ -310,15 +316,11 @@ impl NyashBox for MathBox {
fn as_any(&self) -> &dyn Any { fn as_any(&self) -> &dyn Any {
self self
} }
fn box_id(&self) -> u64 {
self.id
}
} }
impl Display for MathBox { impl Display for MathBox {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "MathBox()") self.fmt_box(f)
} }
} }
@ -326,18 +328,25 @@ impl Display for MathBox {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct FloatBox { pub struct FloatBox {
pub value: f64, pub value: f64,
id: u64, base: BoxBase,
} }
impl FloatBox { impl FloatBox {
pub fn new(value: f64) -> Self { pub fn new(value: f64) -> Self {
static mut COUNTER: u64 = 0; Self {
let id = unsafe { value,
COUNTER += 1; base: BoxBase::new()
COUNTER }
}; }
}
Self { value, id } impl BoxCore for FloatBox {
fn box_id(&self) -> u64 {
self.base.id
}
fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.value)
} }
} }
@ -367,15 +376,11 @@ impl NyashBox for FloatBox {
fn as_any(&self) -> &dyn Any { fn as_any(&self) -> &dyn Any {
self self
} }
fn box_id(&self) -> u64 {
self.id
}
} }
impl Display for FloatBox { impl Display for FloatBox {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.value) self.fmt_box(f)
} }
} }
@ -385,18 +390,17 @@ pub struct RangeBox {
pub start: i64, pub start: i64,
pub end: i64, pub end: i64,
pub step: i64, pub step: i64,
id: u64, base: BoxBase,
} }
impl RangeBox { impl RangeBox {
pub fn new(start: i64, end: i64, step: i64) -> Self { pub fn new(start: i64, end: i64, step: i64) -> Self {
static mut COUNTER: u64 = 0; Self {
let id = unsafe { start,
COUNTER += 1; end,
COUNTER step,
}; base: BoxBase::new()
}
Self { start, end, step, id }
} }
/// イテレータとして値を生成 /// イテレータとして値を生成
@ -420,6 +424,16 @@ impl RangeBox {
} }
} }
impl BoxCore for RangeBox {
fn box_id(&self) -> u64 {
self.base.id
}
fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "Range({}, {}, {})", self.start, self.end, self.step)
}
}
impl NyashBox for RangeBox { impl NyashBox for RangeBox {
fn type_name(&self) -> &'static str { fn type_name(&self) -> &'static str {
"RangeBox" "RangeBox"
@ -448,14 +462,10 @@ impl NyashBox for RangeBox {
fn as_any(&self) -> &dyn Any { fn as_any(&self) -> &dyn Any {
self self
} }
fn box_id(&self) -> u64 {
self.id
}
} }
impl Display for RangeBox { impl Display for RangeBox {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Range({}, {}, {})", self.start, self.end, self.step) self.fmt_box(f)
} }
} }

View File

@ -67,7 +67,7 @@
* - 大きな配列のshuffleは処理時間が長い場合あり * - 大きな配列のshuffleは処理時間が長い場合あり
*/ */
use crate::box_trait::{NyashBox, StringBox, IntegerBox, BoolBox}; use crate::box_trait::{NyashBox, StringBox, IntegerBox, BoolBox, BoxCore, BoxBase};
use crate::boxes::array::ArrayBox; use crate::boxes::array::ArrayBox;
use crate::boxes::math_box::FloatBox; use crate::boxes::math_box::FloatBox;
use std::fmt::{Debug, Display}; use std::fmt::{Debug, Display};
@ -79,17 +79,11 @@ use std::sync::{Arc, Mutex};
pub struct RandomBox { pub struct RandomBox {
// 簡易線形合同法による疑似乱数生成器 // 簡易線形合同法による疑似乱数生成器
seed: Arc<Mutex<u64>>, seed: Arc<Mutex<u64>>,
id: u64, base: BoxBase,
} }
impl RandomBox { impl RandomBox {
pub fn new() -> Self { pub fn new() -> Self {
static mut COUNTER: u64 = 0;
let id = unsafe {
COUNTER += 1;
COUNTER
};
// 現在時刻を種として使用 // 現在時刻を種として使用
let seed = std::time::SystemTime::now() let seed = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH) .duration_since(std::time::UNIX_EPOCH)
@ -98,7 +92,7 @@ impl RandomBox {
Self { Self {
seed: Arc::new(Mutex::new(seed)), seed: Arc::new(Mutex::new(seed)),
id, base: BoxBase::new(),
} }
} }
@ -268,7 +262,7 @@ impl NyashBox for RandomBox {
fn equals(&self, other: &dyn NyashBox) -> BoolBox { fn equals(&self, other: &dyn NyashBox) -> BoolBox {
if let Some(other_random) = other.as_any().downcast_ref::<RandomBox>() { if let Some(other_random) = other.as_any().downcast_ref::<RandomBox>() {
BoolBox::new(self.id == other_random.id) BoolBox::new(self.base.id == other_random.base.id)
} else { } else {
BoolBox::new(false) BoolBox::new(false)
} }
@ -278,13 +272,20 @@ impl NyashBox for RandomBox {
self self
} }
}
impl BoxCore for RandomBox {
fn box_id(&self) -> u64 { fn box_id(&self) -> u64 {
self.id self.base.id
}
fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "RandomBox()")
} }
} }
impl Display for RandomBox { impl Display for RandomBox {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "RandomBox()") self.fmt_box(f)
} }
} }

View File

@ -27,7 +27,7 @@
* result = text.concat(" Nyash") // "Hello, World! Nyash" * result = text.concat(" Nyash") // "Hello, World! Nyash"
* ``` * ```
*/ */
use crate::box_trait::NyashBox; use crate::box_trait::{NyashBox, BoxCore, BoxBase};
use std::any::Any; use std::any::Any;
use std::fmt::Display; use std::fmt::Display;
@ -35,20 +35,14 @@ use std::fmt::Display;
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq)]
pub struct StringBox { pub struct StringBox {
pub value: String, pub value: String,
id: u64, base: BoxBase,
} }
impl StringBox { impl StringBox {
pub fn new(value: impl Into<String>) -> Self { pub fn new(value: impl Into<String>) -> Self {
static mut COUNTER: u64 = 0;
let id = unsafe {
COUNTER += 1;
COUNTER
};
Self { Self {
value: value.into(), value: value.into(),
id, base: BoxBase::new(),
} }
} }
@ -161,13 +155,20 @@ impl NyashBox for StringBox {
self self
} }
}
impl BoxCore for StringBox {
fn box_id(&self) -> u64 { fn box_id(&self) -> u64 {
self.id self.base.id
}
fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "{}", self.value)
} }
} }
impl Display for StringBox { impl Display for StringBox {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.value) self.fmt_box(f)
} }
} }

View File

@ -118,7 +118,7 @@
* - 夏時間切り替え時は計算に注意 * - 夏時間切り替え時は計算に注意
*/ */
use crate::box_trait::{NyashBox, StringBox, IntegerBox, BoolBox}; use crate::box_trait::{NyashBox, StringBox, IntegerBox, BoolBox, BoxCore, BoxBase};
use std::fmt::{Debug, Display}; use std::fmt::{Debug, Display};
use std::any::Any; use std::any::Any;
use std::time::{SystemTime, Duration}; use std::time::{SystemTime, Duration};
@ -127,18 +127,12 @@ use chrono::{DateTime, Local, TimeZone, Datelike, Timelike};
/// 時間操作を提供するBox /// 時間操作を提供するBox
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct TimeBox { pub struct TimeBox {
id: u64, base: BoxBase,
} }
impl TimeBox { impl TimeBox {
pub fn new() -> Self { pub fn new() -> Self {
static mut COUNTER: u64 = 0; Self { base: BoxBase::new() }
let id = unsafe {
COUNTER += 1;
COUNTER
};
Self { id }
} }
/// 現在時刻を取得 /// 現在時刻を取得
@ -208,7 +202,7 @@ impl NyashBox for TimeBox {
fn equals(&self, other: &dyn NyashBox) -> BoolBox { fn equals(&self, other: &dyn NyashBox) -> BoolBox {
if let Some(other_time) = other.as_any().downcast_ref::<TimeBox>() { if let Some(other_time) = other.as_any().downcast_ref::<TimeBox>() {
BoolBox::new(self.id == other_time.id) BoolBox::new(self.base.id == other_time.base.id)
} else { } else {
BoolBox::new(false) BoolBox::new(false)
} }
@ -217,15 +211,21 @@ impl NyashBox for TimeBox {
fn as_any(&self) -> &dyn Any { fn as_any(&self) -> &dyn Any {
self self
} }
}
impl BoxCore for TimeBox {
fn box_id(&self) -> u64 { fn box_id(&self) -> u64 {
self.id self.base.id
}
fn fmt_box(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "TimeBox()")
} }
} }
impl Display for TimeBox { impl Display for TimeBox {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "TimeBox()") self.fmt_box(f)
} }
} }
@ -233,56 +233,38 @@ impl Display for TimeBox {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct DateTimeBox { pub struct DateTimeBox {
pub datetime: DateTime<Local>, pub datetime: DateTime<Local>,
id: u64, base: BoxBase,
} }
impl DateTimeBox { impl DateTimeBox {
/// 現在時刻で作成 /// 現在時刻で作成
pub fn now() -> Self { pub fn now() -> Self {
static mut COUNTER: u64 = 0;
let id = unsafe {
COUNTER += 1;
COUNTER
};
Self { Self {
datetime: Local::now(), datetime: Local::now(),
id, base: BoxBase::new(),
} }
} }
/// UNIXタイムスタンプから作成 /// UNIXタイムスタンプから作成
pub fn from_timestamp(timestamp: i64) -> Self { pub fn from_timestamp(timestamp: i64) -> Self {
static mut COUNTER: u64 = 0;
let id = unsafe {
COUNTER += 1;
COUNTER
};
let datetime = Local.timestamp_opt(timestamp, 0).unwrap(); let datetime = Local.timestamp_opt(timestamp, 0).unwrap();
Self { datetime, id } Self { datetime, base: BoxBase::new() }
} }
/// 文字列からパース /// 文字列からパース
pub fn parse(date_str: &str) -> Result<Self, String> { pub fn parse(date_str: &str) -> Result<Self, String> {
static mut COUNTER: u64 = 0;
let id = unsafe {
COUNTER += 1;
COUNTER
};
// ISO 8601形式でパース // ISO 8601形式でパース
match DateTime::parse_from_rfc3339(date_str) { match DateTime::parse_from_rfc3339(date_str) {
Ok(dt) => Ok(Self { Ok(dt) => Ok(Self {
datetime: dt.with_timezone(&Local), datetime: dt.with_timezone(&Local),
id, base: BoxBase::new(),
}), }),
Err(_) => { Err(_) => {
// シンプルな形式でパース (YYYY-MM-DD HH:MM:SS) // シンプルな形式でパース (YYYY-MM-DD HH:MM:SS)
match chrono::NaiveDateTime::parse_from_str(date_str, "%Y-%m-%d %H:%M:%S") { match chrono::NaiveDateTime::parse_from_str(date_str, "%Y-%m-%d %H:%M:%S") {
Ok(naive_dt) => { Ok(naive_dt) => {
let datetime = Local.from_local_datetime(&naive_dt).unwrap(); let datetime = Local.from_local_datetime(&naive_dt).unwrap();
Ok(Self { datetime, id }) Ok(Self { datetime, base: BoxBase::new() })
} }
Err(e) => Err(format!("Failed to parse date: {}", e)), Err(e) => Err(format!("Failed to parse date: {}", e)),
} }
@ -346,7 +328,7 @@ impl DateTimeBox {
let new_datetime = self.datetime + chrono::Duration::days(int_box.value); let new_datetime = self.datetime + chrono::Duration::days(int_box.value);
Box::new(DateTimeBox { Box::new(DateTimeBox {
datetime: new_datetime, datetime: new_datetime,
id: self.id, base: BoxBase::new(),
}) })
} else { } else {
Box::new(StringBox::new("Error: addDays() requires integer input")) Box::new(StringBox::new("Error: addDays() requires integer input"))
@ -359,7 +341,7 @@ impl DateTimeBox {
let new_datetime = self.datetime + chrono::Duration::hours(int_box.value); let new_datetime = self.datetime + chrono::Duration::hours(int_box.value);
Box::new(DateTimeBox { Box::new(DateTimeBox {
datetime: new_datetime, datetime: new_datetime,
id: self.id, base: BoxBase::new(),
}) })
} else { } else {
Box::new(StringBox::new("Error: addHours() requires integer input")) Box::new(StringBox::new("Error: addHours() requires integer input"))
@ -391,15 +373,21 @@ impl NyashBox for DateTimeBox {
fn as_any(&self) -> &dyn Any { fn as_any(&self) -> &dyn Any {
self self
} }
}
impl BoxCore for DateTimeBox {
fn box_id(&self) -> u64 { fn box_id(&self) -> u64 {
self.id self.base.id
}
fn fmt_box(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.datetime.format("%Y-%m-%d %H:%M:%S"))
} }
} }
impl Display for DateTimeBox { impl Display for DateTimeBox {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.datetime.format("%Y-%m-%d %H:%M:%S")) self.fmt_box(f)
} }
} }
@ -407,20 +395,14 @@ impl Display for DateTimeBox {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct TimerBox { pub struct TimerBox {
start_time: SystemTime, start_time: SystemTime,
id: u64, base: BoxBase,
} }
impl TimerBox { impl TimerBox {
pub fn new() -> Self { pub fn new() -> Self {
static mut COUNTER: u64 = 0;
let id = unsafe {
COUNTER += 1;
COUNTER
};
Self { Self {
start_time: SystemTime::now(), start_time: SystemTime::now(),
id, base: BoxBase::new(),
} }
} }
@ -457,7 +439,7 @@ impl NyashBox for TimerBox {
fn equals(&self, other: &dyn NyashBox) -> BoolBox { fn equals(&self, other: &dyn NyashBox) -> BoolBox {
if let Some(other_timer) = other.as_any().downcast_ref::<TimerBox>() { if let Some(other_timer) = other.as_any().downcast_ref::<TimerBox>() {
BoolBox::new(self.id == other_timer.id) BoolBox::new(self.base.id == other_timer.base.id)
} else { } else {
BoolBox::new(false) BoolBox::new(false)
} }
@ -466,14 +448,20 @@ impl NyashBox for TimerBox {
fn as_any(&self) -> &dyn Any { fn as_any(&self) -> &dyn Any {
self self
} }
}
impl BoxCore for TimerBox {
fn box_id(&self) -> u64 { fn box_id(&self) -> u64 {
self.id self.base.id
}
fn fmt_box(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "TimerBox()")
} }
} }
impl Display for TimerBox { impl Display for TimerBox {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "TimerBox()") self.fmt_box(f)
} }
} }

File diff suppressed because it is too large Load Diff