2025-08-10 11:32:32 +09:00
|
|
|
|
/*! 🔍 DebugBox - デバッグ支援Box
|
|
|
|
|
|
*
|
|
|
|
|
|
* ## 📝 概要
|
|
|
|
|
|
* プロフェッショナル開発向けデバッグ機能を提供するBox。
|
|
|
|
|
|
* メモリ使用量監視、実行トレース、ブレークポイントなど
|
|
|
|
|
|
* 高度なデバッグ機能を完備。
|
|
|
|
|
|
*
|
|
|
|
|
|
* ## 🛠️ 利用可能メソッド
|
|
|
|
|
|
*
|
|
|
|
|
|
* ### 🎯 基本デバッグ
|
|
|
|
|
|
* - `startTracking()` - デバッグ追跡開始
|
|
|
|
|
|
* - `stopTracking()` - デバッグ追跡停止
|
|
|
|
|
|
* - `trackBox(box, name)` - 特定Boxを追跡対象に追加
|
|
|
|
|
|
* - `watch(box, name)` - リアルタイム監視
|
|
|
|
|
|
* - `clear()` - 全デバッグ情報クリア
|
|
|
|
|
|
*
|
|
|
|
|
|
* ### 📊 レポート・分析
|
|
|
|
|
|
* - `dumpAll()` - 全追跡データダンプ
|
|
|
|
|
|
* - `memoryReport()` - メモリ使用量レポート
|
|
|
|
|
|
* - `showCallStack()` - 関数呼び出しスタック表示
|
|
|
|
|
|
* - `saveToFile(filename)` - デバッグ情報をファイル保存
|
|
|
|
|
|
*
|
|
|
|
|
|
* ### 🎮 高度機能
|
|
|
|
|
|
* - `setBreakpoint(function)` - ブレークポイント設定
|
|
|
|
|
|
* - `traceCall(function, args)` - 関数呼び出しトレース
|
|
|
|
|
|
* - `isTracking()` - 追跡状態確認
|
|
|
|
|
|
* - `getTrackedCount()` - 追跡中Box数取得
|
|
|
|
|
|
*
|
|
|
|
|
|
* ## 💡 使用例
|
|
|
|
|
|
* ```nyash
|
|
|
|
|
|
* local debug, user, product
|
|
|
|
|
|
* debug = new DebugBox()
|
|
|
|
|
|
*
|
|
|
|
|
|
* // デバッグ開始
|
|
|
|
|
|
* debug.startTracking()
|
|
|
|
|
|
*
|
|
|
|
|
|
* // オブジェクトを追跡
|
|
|
|
|
|
* user = new User("Alice", 25)
|
|
|
|
|
|
* debug.trackBox(user, "user_alice")
|
|
|
|
|
|
*
|
|
|
|
|
|
* product = new Product("Book", 1500)
|
|
|
|
|
|
* debug.trackBox(product, "book_product")
|
|
|
|
|
|
*
|
|
|
|
|
|
* // リアルタイム監視
|
|
|
|
|
|
* debug.watch(user.age, "user_age")
|
|
|
|
|
|
*
|
|
|
|
|
|
* // レポート生成
|
|
|
|
|
|
* print(debug.memoryReport())
|
|
|
|
|
|
* print(debug.dumpAll())
|
|
|
|
|
|
*
|
|
|
|
|
|
* // ファイルに保存
|
|
|
|
|
|
* debug.saveToFile("debug_report.txt")
|
|
|
|
|
|
* ```
|
|
|
|
|
|
*
|
|
|
|
|
|
* ## 🎮 実用例 - パフォーマンス診断
|
|
|
|
|
|
* ```nyash
|
|
|
|
|
|
* static box PerformanceTest {
|
|
|
|
|
|
* init { debug, data, results }
|
|
|
|
|
|
*
|
|
|
|
|
|
* main() {
|
|
|
|
|
|
* me.debug = new DebugBox()
|
|
|
|
|
|
* me.debug.startTracking()
|
|
|
|
|
|
*
|
|
|
|
|
|
* // 大量データ処理のテスト
|
|
|
|
|
|
* me.data = []
|
|
|
|
|
|
* loop(i < 1000) {
|
|
|
|
|
|
* me.data.push("item_" + i.toString())
|
|
|
|
|
|
* }
|
|
|
|
|
|
* me.debug.trackBox(me.data, "large_array")
|
|
|
|
|
|
*
|
|
|
|
|
|
* // 処理実行
|
|
|
|
|
|
* me.processData()
|
|
|
|
|
|
*
|
|
|
|
|
|
* // 結果分析
|
|
|
|
|
|
* print(me.debug.memoryReport())
|
|
|
|
|
|
* }
|
|
|
|
|
|
* }
|
|
|
|
|
|
* ```
|
|
|
|
|
|
*
|
|
|
|
|
|
* ## ⚡ ベストプラクティス
|
|
|
|
|
|
* ```nyash
|
|
|
|
|
|
* // エラーハンドリング付きデバッグ
|
|
|
|
|
|
* local debug
|
|
|
|
|
|
* debug = new DebugBox()
|
|
|
|
|
|
*
|
|
|
|
|
|
* try {
|
|
|
|
|
|
* debug.startTracking()
|
|
|
|
|
|
* // 問題のあるコード
|
|
|
|
|
|
* risky_operation()
|
|
|
|
|
|
* } catch (error) {
|
|
|
|
|
|
* debug.saveToFile("error_dump.txt")
|
|
|
|
|
|
* print("Debug info saved to error_dump.txt")
|
|
|
|
|
|
* }
|
|
|
|
|
|
* ```
|
|
|
|
|
|
*
|
|
|
|
|
|
* ## ⚠️ 注意
|
|
|
|
|
|
* - 本格運用時はtrackingを無効にしてパフォーマンス向上
|
|
|
|
|
|
* - 大量データ追跡時はメモリ消費に注意
|
|
|
|
|
|
* - call stackは直近100件まで自動保持
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2025-08-09 15:14:44 +09:00
|
|
|
|
use std::collections::HashMap;
|
2025-08-14 23:59:11 +00:00
|
|
|
|
use std::sync::RwLock;
|
2025-08-09 15:14:44 +09:00
|
|
|
|
use chrono::Local;
|
2025-08-15 03:08:09 +00:00
|
|
|
|
use crate::box_trait::{BoxCore, BoxBase, NyashBox, StringBox, BoolBox, VoidBox};
|
2025-08-09 15:14:44 +09:00
|
|
|
|
use crate::interpreter::RuntimeError;
|
|
|
|
|
|
use crate::instance::InstanceBox;
|
|
|
|
|
|
use std::any::Any;
|
|
|
|
|
|
|
2025-08-15 03:08:09 +00:00
|
|
|
|
#[derive(Debug)]
|
2025-08-09 15:14:44 +09:00
|
|
|
|
pub struct DebugBox {
|
🚀 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>
2025-08-11 11:25:17 +09:00
|
|
|
|
base: BoxBase,
|
2025-08-14 23:59:11 +00:00
|
|
|
|
tracking_enabled: RwLock<bool>,
|
|
|
|
|
|
tracked_boxes: RwLock<HashMap<String, TrackedBoxInfo>>,
|
|
|
|
|
|
breakpoints: RwLock<Vec<String>>,
|
|
|
|
|
|
call_stack: RwLock<Vec<CallInfo>>,
|
2025-08-09 15:14:44 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
|
|
struct TrackedBoxInfo {
|
|
|
|
|
|
box_type: String,
|
|
|
|
|
|
created_at: String,
|
|
|
|
|
|
fields: String,
|
|
|
|
|
|
value_repr: String,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
|
|
struct CallInfo {
|
|
|
|
|
|
function_name: String,
|
|
|
|
|
|
args: Vec<String>,
|
|
|
|
|
|
timestamp: String,
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl DebugBox {
|
|
|
|
|
|
pub fn new() -> Self {
|
|
|
|
|
|
DebugBox {
|
🚀 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>
2025-08-11 11:25:17 +09:00
|
|
|
|
base: BoxBase::new(),
|
2025-08-14 23:59:11 +00:00
|
|
|
|
tracking_enabled: RwLock::new(false),
|
|
|
|
|
|
tracked_boxes: RwLock::new(HashMap::new()),
|
|
|
|
|
|
breakpoints: RwLock::new(Vec::new()),
|
|
|
|
|
|
call_stack: RwLock::new(Vec::new()),
|
2025-08-09 15:14:44 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn start_tracking(&self) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
2025-08-14 23:59:11 +00:00
|
|
|
|
let mut enabled = self.tracking_enabled.write().unwrap();
|
2025-08-09 15:14:44 +09:00
|
|
|
|
*enabled = true;
|
|
|
|
|
|
println!("[DEBUG] Tracking started");
|
|
|
|
|
|
Ok(Box::new(VoidBox::new()))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn stop_tracking(&self) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
2025-08-14 23:59:11 +00:00
|
|
|
|
let mut enabled = self.tracking_enabled.write().unwrap();
|
2025-08-09 15:14:44 +09:00
|
|
|
|
*enabled = false;
|
|
|
|
|
|
println!("[DEBUG] Tracking stopped");
|
|
|
|
|
|
Ok(Box::new(VoidBox::new()))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn track_box(&self, box_value: &dyn NyashBox, name: &str) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
2025-08-14 23:59:11 +00:00
|
|
|
|
let enabled = self.tracking_enabled.read().unwrap();
|
2025-08-09 15:14:44 +09:00
|
|
|
|
if !*enabled {
|
|
|
|
|
|
return Ok(Box::new(VoidBox::new()));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-14 23:59:11 +00:00
|
|
|
|
let mut tracked = self.tracked_boxes.write().unwrap();
|
2025-08-09 15:14:44 +09:00
|
|
|
|
|
|
|
|
|
|
let info = TrackedBoxInfo {
|
|
|
|
|
|
box_type: box_value.type_name().to_string(),
|
|
|
|
|
|
created_at: Local::now().format("%Y-%m-%d %H:%M:%S").to_string(),
|
|
|
|
|
|
fields: self.get_box_fields(box_value),
|
|
|
|
|
|
value_repr: box_value.to_string_box().value,
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
tracked.insert(name.to_string(), info);
|
|
|
|
|
|
|
|
|
|
|
|
Ok(Box::new(VoidBox::new()))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn get_box_fields(&self, box_value: &dyn NyashBox) -> String {
|
|
|
|
|
|
// Try to downcast to InstanceBox to get fields
|
|
|
|
|
|
if let Some(instance) = box_value.as_any().downcast_ref::<InstanceBox>() {
|
|
|
|
|
|
let fields = instance.fields.lock().unwrap();
|
|
|
|
|
|
let field_names: Vec<String> = fields.keys().cloned().collect();
|
|
|
|
|
|
field_names.join(", ")
|
|
|
|
|
|
} else {
|
|
|
|
|
|
"N/A".to_string()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn dump_all(&self) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
2025-08-15 03:08:09 +00:00
|
|
|
|
let tracked = self.tracked_boxes.read().unwrap();
|
2025-08-09 15:14:44 +09:00
|
|
|
|
let mut output = String::from("=== Box State Dump ===\n");
|
|
|
|
|
|
output.push_str(&format!("Time: {}\n", Local::now().format("%Y-%m-%d %H:%M:%S")));
|
|
|
|
|
|
output.push_str(&format!("Total tracked boxes: {}\n\n", tracked.len()));
|
|
|
|
|
|
|
|
|
|
|
|
for (name, info) in tracked.iter() {
|
|
|
|
|
|
output.push_str(&format!("Box: {}\n", name));
|
|
|
|
|
|
output.push_str(&format!(" Type: {}\n", info.box_type));
|
|
|
|
|
|
output.push_str(&format!(" Created: {}\n", info.created_at));
|
|
|
|
|
|
output.push_str(&format!(" Fields: {}\n", info.fields));
|
|
|
|
|
|
output.push_str(&format!(" Value: {}\n", info.value_repr));
|
|
|
|
|
|
output.push_str("\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Ok(Box::new(StringBox::new(output)))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn save_to_file(&self, filename: &str) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
|
|
|
|
|
let dump_result = self.dump_all()?;
|
|
|
|
|
|
let content = dump_result.to_string_box().value;
|
|
|
|
|
|
|
|
|
|
|
|
// Write to file using std::fs
|
|
|
|
|
|
std::fs::write(filename, content)
|
|
|
|
|
|
.map_err(|e| RuntimeError::InvalidOperation {
|
|
|
|
|
|
message: format!("Failed to write debug file: {}", e),
|
|
|
|
|
|
})?;
|
|
|
|
|
|
|
|
|
|
|
|
println!("[DEBUG] Saved debug info to {}", filename);
|
|
|
|
|
|
Ok(Box::new(VoidBox::new()))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn watch(&self, box_value: &dyn NyashBox, name: &str) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
|
|
|
|
|
let value_str = box_value.to_string_box().value;
|
|
|
|
|
|
let type_name = box_value.type_name();
|
|
|
|
|
|
|
|
|
|
|
|
println!("[DEBUG] Watching {} ({}): {}", name, type_name, value_str);
|
|
|
|
|
|
Ok(Box::new(VoidBox::new()))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn memory_report(&self) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
2025-08-15 03:08:09 +00:00
|
|
|
|
let tracked = self.tracked_boxes.read().unwrap();
|
2025-08-09 15:14:44 +09:00
|
|
|
|
let mut report = String::from("=== Memory Report ===\n");
|
|
|
|
|
|
report.push_str(&format!("Tracked boxes: {}\n", tracked.len()));
|
|
|
|
|
|
|
|
|
|
|
|
// Count by type
|
|
|
|
|
|
let mut type_counts: HashMap<String, usize> = HashMap::new();
|
|
|
|
|
|
for info in tracked.values() {
|
|
|
|
|
|
*type_counts.entry(info.box_type.clone()).or_insert(0) += 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
report.push_str("\nBoxes by type:\n");
|
|
|
|
|
|
for (box_type, count) in type_counts.iter() {
|
|
|
|
|
|
report.push_str(&format!(" {}: {}\n", box_type, count));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Ok(Box::new(StringBox::new(report)))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Advanced features
|
|
|
|
|
|
pub fn set_breakpoint(&self, function_name: &str) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
2025-08-15 03:08:09 +00:00
|
|
|
|
let mut breakpoints = self.breakpoints.write().unwrap();
|
2025-08-09 15:14:44 +09:00
|
|
|
|
breakpoints.push(function_name.to_string());
|
|
|
|
|
|
println!("[DEBUG] Breakpoint set at function: {}", function_name);
|
|
|
|
|
|
Ok(Box::new(VoidBox::new()))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn trace_call(&self, function_name: &str, args: Vec<String>) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
2025-08-15 03:08:09 +00:00
|
|
|
|
let mut stack = self.call_stack.write().unwrap();
|
2025-08-09 15:14:44 +09:00
|
|
|
|
stack.push(CallInfo {
|
|
|
|
|
|
function_name: function_name.to_string(),
|
|
|
|
|
|
args,
|
|
|
|
|
|
timestamp: Local::now().format("%H:%M:%S.%3f").to_string(),
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
// Keep only last 100 calls to prevent memory issues
|
|
|
|
|
|
if stack.len() > 100 {
|
|
|
|
|
|
stack.remove(0);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Ok(Box::new(VoidBox::new()))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn show_call_stack(&self) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
2025-08-15 03:08:09 +00:00
|
|
|
|
let stack = self.call_stack.read().unwrap();
|
2025-08-09 15:14:44 +09:00
|
|
|
|
let mut output = String::from("=== Call Stack ===\n");
|
|
|
|
|
|
|
|
|
|
|
|
for (i, call) in stack.iter().enumerate() {
|
|
|
|
|
|
output.push_str(&format!("{}: [{}] {}({})\n",
|
|
|
|
|
|
i,
|
|
|
|
|
|
call.timestamp,
|
|
|
|
|
|
call.function_name,
|
|
|
|
|
|
call.args.join(", ")
|
|
|
|
|
|
));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Ok(Box::new(StringBox::new(output)))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn clear(&self) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
2025-08-15 03:08:09 +00:00
|
|
|
|
let mut tracked = self.tracked_boxes.write().unwrap();
|
2025-08-09 15:14:44 +09:00
|
|
|
|
tracked.clear();
|
|
|
|
|
|
|
2025-08-15 03:08:09 +00:00
|
|
|
|
let mut stack = self.call_stack.write().unwrap();
|
2025-08-09 15:14:44 +09:00
|
|
|
|
stack.clear();
|
|
|
|
|
|
|
|
|
|
|
|
println!("[DEBUG] Cleared all debug information");
|
|
|
|
|
|
Ok(Box::new(VoidBox::new()))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn is_tracking(&self) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
2025-08-14 23:59:11 +00:00
|
|
|
|
let enabled = self.tracking_enabled.read().unwrap();
|
2025-08-09 15:14:44 +09:00
|
|
|
|
Ok(Box::new(BoolBox::new(*enabled)))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
pub fn get_tracked_count(&self) -> Result<Box<dyn NyashBox>, RuntimeError> {
|
2025-08-15 03:08:09 +00:00
|
|
|
|
let tracked = self.tracked_boxes.read().unwrap();
|
2025-08-09 15:14:44 +09:00
|
|
|
|
Ok(Box::new(crate::box_trait::IntegerBox::new(tracked.len() as i64)))
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-15 03:08:09 +00:00
|
|
|
|
// Manual Clone implementation for DebugBox (RwLock doesn't auto-derive Clone)
|
|
|
|
|
|
impl Clone for DebugBox {
|
|
|
|
|
|
fn clone(&self) -> Self {
|
|
|
|
|
|
let tracked = self.tracked_boxes.read().unwrap();
|
|
|
|
|
|
let breakpoints = self.breakpoints.read().unwrap();
|
|
|
|
|
|
let call_stack = self.call_stack.read().unwrap();
|
|
|
|
|
|
let tracking_enabled = self.tracking_enabled.read().unwrap();
|
|
|
|
|
|
|
|
|
|
|
|
DebugBox {
|
|
|
|
|
|
base: BoxBase::new(), // New unique ID for cloned instance
|
|
|
|
|
|
tracking_enabled: RwLock::new(*tracking_enabled),
|
|
|
|
|
|
tracked_boxes: RwLock::new(tracked.clone()),
|
|
|
|
|
|
breakpoints: RwLock::new(breakpoints.clone()),
|
|
|
|
|
|
call_stack: RwLock::new(call_stack.clone()),
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
🚀 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>
2025-08-11 11:25:17 +09:00
|
|
|
|
// Implement BoxCore trait for DebugBox
|
|
|
|
|
|
impl BoxCore for DebugBox {
|
|
|
|
|
|
fn box_id(&self) -> u64 {
|
|
|
|
|
|
self.base.id
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-11 15:01:11 +09:00
|
|
|
|
fn parent_type_id(&self) -> Option<std::any::TypeId> {
|
|
|
|
|
|
self.base.parent_type_id
|
|
|
|
|
|
}
|
|
|
|
|
|
|
🚀 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>
2025-08-11 11:25:17 +09:00
|
|
|
|
fn fmt_box(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
2025-08-15 03:08:09 +00:00
|
|
|
|
let tracked = self.tracked_boxes.read().unwrap();
|
🚀 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>
2025-08-11 11:25:17 +09:00
|
|
|
|
write!(f, "DebugBox[{} tracked]", tracked.len())
|
|
|
|
|
|
}
|
2025-08-11 15:01:11 +09:00
|
|
|
|
|
|
|
|
|
|
fn as_any(&self) -> &dyn Any {
|
|
|
|
|
|
self
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn as_any_mut(&mut self) -> &mut dyn Any {
|
|
|
|
|
|
self
|
|
|
|
|
|
}
|
🚀 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>
2025-08-11 11:25:17 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 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)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-09 15:14:44 +09:00
|
|
|
|
// Implement NyashBox trait for DebugBox
|
|
|
|
|
|
impl NyashBox for DebugBox {
|
|
|
|
|
|
fn to_string_box(&self) -> StringBox {
|
2025-08-15 03:08:09 +00:00
|
|
|
|
let tracked = self.tracked_boxes.read().unwrap();
|
2025-08-09 15:14:44 +09:00
|
|
|
|
StringBox::new(format!("DebugBox[{} tracked]", tracked.len()))
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn equals(&self, other: &dyn NyashBox) -> BoolBox {
|
|
|
|
|
|
if let Some(other_debug) = other.as_any().downcast_ref::<DebugBox>() {
|
🚀 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>
2025-08-11 11:25:17 +09:00
|
|
|
|
BoolBox::new(self.base.id == other_debug.base.id)
|
2025-08-09 15:14:44 +09:00
|
|
|
|
} else {
|
|
|
|
|
|
BoolBox::new(false)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn type_name(&self) -> &'static str {
|
|
|
|
|
|
"DebugBox"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn clone_box(&self) -> Box<dyn NyashBox> {
|
|
|
|
|
|
Box::new(self.clone())
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|