2025-08-12 01:35:36 +00:00
|
|
|
|
/*! 📦 IntentBox - Structured Message Box
|
2025-08-11 05:11:52 +09:00
|
|
|
|
*
|
|
|
|
|
|
* ## 📝 概要
|
2025-08-12 01:35:36 +00:00
|
|
|
|
* IntentBoxは構造化メッセージを表現するBoxです。
|
|
|
|
|
|
* P2P通信において、メッセージの種類(name)と内容(payload)を
|
|
|
|
|
|
* 明確に分離して管理します。
|
|
|
|
|
|
*
|
|
|
|
|
|
* ## 🏗️ 設計
|
|
|
|
|
|
* - **name**: メッセージの種類 ("chat.message", "file.share"等)
|
|
|
|
|
|
* - **payload**: JSON形式の任意データ
|
|
|
|
|
|
* - **Arc<Mutex>**: 他のBoxと統一されたメモリ管理パターン
|
2025-08-11 05:11:52 +09:00
|
|
|
|
*
|
|
|
|
|
|
* ## 🛠️ 利用可能メソッド
|
2025-08-12 01:35:36 +00:00
|
|
|
|
* - `new(name, payload)` - 構造化メッセージを作成
|
|
|
|
|
|
* - `getName()` - メッセージ名を取得
|
|
|
|
|
|
* - `getPayload()` - ペイロードを取得
|
|
|
|
|
|
* - `setPayload(data)` - ペイロードを更新
|
2025-08-11 05:11:52 +09:00
|
|
|
|
*
|
|
|
|
|
|
* ## 💡 使用例
|
|
|
|
|
|
* ```nyash
|
2025-08-12 01:35:36 +00:00
|
|
|
|
* // チャットメッセージ
|
|
|
|
|
|
* local msg = new IntentBox("chat.message", {
|
|
|
|
|
|
* text: "Hello P2P!",
|
|
|
|
|
|
* from: "alice"
|
|
|
|
|
|
* })
|
2025-08-11 05:11:52 +09:00
|
|
|
|
*
|
2025-08-12 01:35:36 +00:00
|
|
|
|
* // ファイル共有メッセージ
|
|
|
|
|
|
* local file_msg = new IntentBox("file.share", {
|
|
|
|
|
|
* filename: "document.pdf",
|
|
|
|
|
|
* size: 1024000
|
2025-08-11 05:11:52 +09:00
|
|
|
|
* })
|
|
|
|
|
|
* ```
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2025-08-11 12:09:14 +09:00
|
|
|
|
use crate::box_trait::{NyashBox, StringBox, BoolBox, BoxCore, BoxBase};
|
2025-08-11 05:11:52 +09:00
|
|
|
|
use std::any::Any;
|
|
|
|
|
|
use std::sync::{Arc, Mutex};
|
|
|
|
|
|
use std::fmt::{self, Debug};
|
|
|
|
|
|
|
2025-08-12 01:35:36 +00:00
|
|
|
|
/// IntentBox内部データ構造
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
|
|
pub struct IntentBoxData {
|
2025-08-11 12:09:14 +09:00
|
|
|
|
base: BoxBase,
|
2025-08-12 01:35:36 +00:00
|
|
|
|
/// メッセージの種類 ("chat.message", "file.share"等)
|
|
|
|
|
|
pub name: String,
|
|
|
|
|
|
/// 任意のJSONデータ
|
|
|
|
|
|
pub payload: serde_json::Value,
|
2025-08-11 05:11:52 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-12 01:35:36 +00:00
|
|
|
|
/// IntentBox - 構造化メッセージBox(Arc<Mutex>統一パターン)
|
|
|
|
|
|
pub type IntentBox = Arc<Mutex<IntentBoxData>>;
|
2025-08-11 05:11:52 +09:00
|
|
|
|
|
2025-08-12 01:35:36 +00:00
|
|
|
|
impl IntentBoxData {
|
|
|
|
|
|
/// 新しいIntentBoxを作成
|
|
|
|
|
|
pub fn new(name: String, payload: serde_json::Value) -> IntentBox {
|
|
|
|
|
|
Arc::new(Mutex::new(IntentBoxData {
|
2025-08-11 12:09:14 +09:00
|
|
|
|
base: BoxBase::new(),
|
2025-08-12 01:35:36 +00:00
|
|
|
|
name,
|
|
|
|
|
|
payload,
|
|
|
|
|
|
}))
|
2025-08-11 05:11:52 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-12 01:35:36 +00:00
|
|
|
|
/// メッセージ名を取得
|
|
|
|
|
|
pub fn get_name(&self) -> &str {
|
|
|
|
|
|
&self.name
|
2025-08-11 05:11:52 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-12 01:35:36 +00:00
|
|
|
|
/// ペイロードを取得
|
|
|
|
|
|
pub fn get_payload(&self) -> &serde_json::Value {
|
|
|
|
|
|
&self.payload
|
2025-08-11 05:11:52 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-12 01:35:36 +00:00
|
|
|
|
/// ペイロードを更新
|
|
|
|
|
|
pub fn set_payload(&mut self, payload: serde_json::Value) {
|
|
|
|
|
|
self.payload = payload;
|
2025-08-11 05:11:52 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl NyashBox for IntentBox {
|
|
|
|
|
|
fn to_string_box(&self) -> StringBox {
|
2025-08-12 01:35:36 +00:00
|
|
|
|
let data = self.lock().unwrap();
|
|
|
|
|
|
StringBox::new(format!("IntentBox[{}]", data.name))
|
2025-08-11 05:11:52 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn equals(&self, other: &dyn NyashBox) -> BoolBox {
|
|
|
|
|
|
if let Some(other_intent) = other.as_any().downcast_ref::<IntentBox>() {
|
2025-08-12 01:35:36 +00:00
|
|
|
|
let self_data = self.lock().unwrap();
|
|
|
|
|
|
let other_data = other_intent.lock().unwrap();
|
|
|
|
|
|
BoolBox::new(self_data.base.id == other_data.base.id)
|
2025-08-11 05:11:52 +09:00
|
|
|
|
} else {
|
|
|
|
|
|
BoolBox::new(false)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn type_name(&self) -> &'static str {
|
|
|
|
|
|
"IntentBox"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn clone_box(&self) -> Box<dyn NyashBox> {
|
2025-08-12 01:35:36 +00:00
|
|
|
|
let data = self.lock().unwrap();
|
|
|
|
|
|
Box::new(IntentBoxData::new(data.name.clone(), data.payload.clone()))
|
2025-08-11 05:11:52 +09:00
|
|
|
|
}
|
2025-08-11 12:09:14 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl BoxCore for IntentBox {
|
2025-08-11 05:11:52 +09:00
|
|
|
|
fn box_id(&self) -> u64 {
|
2025-08-12 01:35:36 +00:00
|
|
|
|
self.lock().unwrap().base.id
|
2025-08-11 15:01:11 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn parent_type_id(&self) -> Option<std::any::TypeId> {
|
2025-08-12 01:35:36 +00:00
|
|
|
|
self.lock().unwrap().base.parent_type_id
|
2025-08-11 12:09:14 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn fmt_box(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
2025-08-12 01:35:36 +00:00
|
|
|
|
let data = self.lock().unwrap();
|
|
|
|
|
|
write!(f, "IntentBox[{}]", data.name)
|
2025-08-11 12:09:14 +09:00
|
|
|
|
}
|
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
|
|
|
|
|
|
}
|
2025-08-11 12:09:14 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-08-12 01:35:36 +00:00
|
|
|
|
impl std::fmt::Display for IntentBoxData {
|
2025-08-11 12:09:14 +09:00
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
2025-08-12 01:35:36 +00:00
|
|
|
|
write!(f, "IntentBox[{}]", self.name)
|
2025-08-11 05:11:52 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|