2025-08-09 15:14:44 +09:00
|
|
|
|
/*!
|
|
|
|
|
|
* Nyash P2P Channel System - Arrow構文によるBox間通信
|
2025-09-17 07:43:07 +09:00
|
|
|
|
*
|
2025-08-09 15:14:44 +09:00
|
|
|
|
* alice >> bob でメッセージ送信を可能にする
|
|
|
|
|
|
* Everything is Box哲学に基づくP2P通信システム
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
2025-09-17 07:43:07 +09:00
|
|
|
|
use crate::box_trait::{BoxBase, BoxCore, NyashBox, StringBox, VoidBox};
|
|
|
|
|
|
use std::any::Any;
|
2025-08-09 15:14:44 +09:00
|
|
|
|
use std::collections::HashMap;
|
|
|
|
|
|
use std::fmt::{Debug, Display};
|
2025-09-17 07:43:07 +09:00
|
|
|
|
use std::sync::{Arc, Mutex, Weak};
|
2025-08-09 15:14:44 +09:00
|
|
|
|
|
|
|
|
|
|
/// チャンネル - Box間の通信路
|
|
|
|
|
|
#[derive(Clone)]
|
|
|
|
|
|
pub struct ChannelBox {
|
|
|
|
|
|
/// 送信者の名前
|
|
|
|
|
|
pub sender_name: String,
|
2025-09-17 07:43:07 +09:00
|
|
|
|
|
2025-08-09 15:14:44 +09:00
|
|
|
|
/// 受信者の名前
|
|
|
|
|
|
pub receiver_name: String,
|
2025-09-17 07:43:07 +09:00
|
|
|
|
|
2025-08-09 15:14:44 +09:00
|
|
|
|
/// リンクされたBox(弱参照)
|
|
|
|
|
|
linked_boxes: Arc<Mutex<HashMap<String, Weak<Mutex<dyn NyashBox>>>>>,
|
2025-09-17 07:43:07 +09:00
|
|
|
|
|
2025-08-09 15:14:44 +09:00
|
|
|
|
/// メッセージハンドラー
|
2025-09-17 07:43:07 +09:00
|
|
|
|
handlers:
|
|
|
|
|
|
Arc<Mutex<HashMap<String, Box<dyn Fn(Box<dyn NyashBox>) -> Box<dyn NyashBox> + Send>>>>,
|
|
|
|
|
|
|
2025-08-11 12:09:14 +09:00
|
|
|
|
/// Box基底
|
|
|
|
|
|
base: BoxBase,
|
2025-08-09 15:14:44 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl ChannelBox {
|
|
|
|
|
|
/// 新しいチャンネルを作成
|
|
|
|
|
|
pub fn new(sender: &str, receiver: &str) -> Self {
|
|
|
|
|
|
Self {
|
|
|
|
|
|
sender_name: sender.to_string(),
|
|
|
|
|
|
receiver_name: receiver.to_string(),
|
|
|
|
|
|
linked_boxes: Arc::new(Mutex::new(HashMap::new())),
|
|
|
|
|
|
handlers: Arc::new(Mutex::new(HashMap::new())),
|
2025-08-11 12:09:14 +09:00
|
|
|
|
base: BoxBase::new(),
|
2025-08-09 15:14:44 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
|
|
2025-08-09 15:14:44 +09:00
|
|
|
|
/// Boxをリンク
|
|
|
|
|
|
pub fn link(&self, name: &str, target: Arc<Mutex<dyn NyashBox>>) {
|
2025-09-17 07:43:07 +09:00
|
|
|
|
self.linked_boxes
|
|
|
|
|
|
.lock()
|
|
|
|
|
|
.unwrap()
|
|
|
|
|
|
.insert(name.to_string(), Arc::downgrade(&target));
|
2025-08-09 15:14:44 +09:00
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
|
|
2025-08-09 15:14:44 +09:00
|
|
|
|
/// メッセージハンドラーを登録
|
|
|
|
|
|
pub fn register_handler<F>(&self, method: &str, handler: F)
|
|
|
|
|
|
where
|
2025-09-17 07:43:07 +09:00
|
|
|
|
F: Fn(Box<dyn NyashBox>) -> Box<dyn NyashBox> + Send + 'static,
|
2025-08-09 15:14:44 +09:00
|
|
|
|
{
|
2025-09-17 07:43:07 +09:00
|
|
|
|
self.handlers
|
|
|
|
|
|
.lock()
|
|
|
|
|
|
.unwrap()
|
|
|
|
|
|
.insert(method.to_string(), Box::new(handler));
|
2025-08-09 15:14:44 +09:00
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
|
|
2025-08-09 15:14:44 +09:00
|
|
|
|
/// メソッド呼び出しを実行
|
|
|
|
|
|
pub fn invoke(&self, method: &str, args: Vec<Box<dyn NyashBox>>) -> Box<dyn NyashBox> {
|
|
|
|
|
|
// "*" はブロードキャスト
|
|
|
|
|
|
if self.receiver_name == "*" {
|
|
|
|
|
|
return self.broadcast(method, args);
|
|
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
|
|
2025-08-09 15:14:44 +09:00
|
|
|
|
// 通常の送信
|
|
|
|
|
|
let handlers = self.handlers.lock().unwrap();
|
|
|
|
|
|
if let Some(handler) = handlers.get(method) {
|
|
|
|
|
|
// 簡易実装:最初の引数のみ使用
|
2025-09-17 07:43:07 +09:00
|
|
|
|
let arg = args
|
|
|
|
|
|
.get(0)
|
2025-08-09 15:14:44 +09:00
|
|
|
|
.map(|a| a.clone_box())
|
|
|
|
|
|
.unwrap_or_else(|| Box::new(VoidBox::new()));
|
|
|
|
|
|
handler(arg)
|
|
|
|
|
|
} else {
|
2025-09-17 07:43:07 +09:00
|
|
|
|
Box::new(StringBox::new(&format!(
|
|
|
|
|
|
"No handler for method: {}",
|
|
|
|
|
|
method
|
|
|
|
|
|
)))
|
2025-08-09 15:14:44 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
|
|
2025-08-09 15:14:44 +09:00
|
|
|
|
/// 送信者名を取得
|
|
|
|
|
|
pub fn sender(&self) -> Box<dyn NyashBox> {
|
|
|
|
|
|
Box::new(StringBox::new(&self.sender_name))
|
|
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
|
|
2025-08-09 15:14:44 +09:00
|
|
|
|
/// 受信者名を取得
|
|
|
|
|
|
pub fn receiver(&self) -> Box<dyn NyashBox> {
|
|
|
|
|
|
Box::new(StringBox::new(&self.receiver_name))
|
|
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
|
|
2025-08-09 15:14:44 +09:00
|
|
|
|
/// ブロードキャスト
|
|
|
|
|
|
fn broadcast(&self, _method: &str, _args: Vec<Box<dyn NyashBox>>) -> Box<dyn NyashBox> {
|
|
|
|
|
|
let linked = self.linked_boxes.lock().unwrap();
|
|
|
|
|
|
let mut results = Vec::new();
|
2025-09-17 07:43:07 +09:00
|
|
|
|
|
2025-08-09 15:14:44 +09:00
|
|
|
|
for (name, weak_box) in linked.iter() {
|
|
|
|
|
|
if let Some(_strong_box) = weak_box.upgrade() {
|
|
|
|
|
|
// 各Boxにメッセージを送信
|
|
|
|
|
|
results.push(format!("Sent to {}", name));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
|
|
|
|
|
|
|
Box::new(StringBox::new(&format!(
|
|
|
|
|
|
"Broadcast complete: {:?}",
|
|
|
|
|
|
results
|
|
|
|
|
|
)))
|
2025-08-09 15:14:44 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl NyashBox for ChannelBox {
|
|
|
|
|
|
fn type_name(&self) -> &'static str {
|
|
|
|
|
|
"ChannelBox"
|
|
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
|
|
2025-08-09 15:14:44 +09:00
|
|
|
|
fn to_string_box(&self) -> StringBox {
|
2025-09-17 07:43:07 +09:00
|
|
|
|
StringBox::new(&format!(
|
|
|
|
|
|
"Channel({} >> {})",
|
|
|
|
|
|
self.sender_name, self.receiver_name
|
|
|
|
|
|
))
|
2025-08-09 15:14:44 +09:00
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
|
|
2025-08-09 15:14:44 +09:00
|
|
|
|
fn clone_box(&self) -> Box<dyn NyashBox> {
|
|
|
|
|
|
Box::new(self.clone())
|
|
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
|
|
2025-08-15 14:29:47 +09:00
|
|
|
|
/// 仮実装: clone_boxと同じ(後で修正)
|
|
|
|
|
|
fn share_box(&self) -> Box<dyn NyashBox> {
|
|
|
|
|
|
self.clone_box()
|
|
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
|
|
2025-08-09 15:14:44 +09:00
|
|
|
|
fn equals(&self, other: &dyn NyashBox) -> crate::box_trait::BoolBox {
|
|
|
|
|
|
if let Some(other_channel) = other.as_any().downcast_ref::<ChannelBox>() {
|
|
|
|
|
|
crate::box_trait::BoolBox::new(
|
2025-09-17 07:43:07 +09:00
|
|
|
|
self.sender_name == other_channel.sender_name
|
|
|
|
|
|
&& self.receiver_name == other_channel.receiver_name,
|
2025-08-09 15:14:44 +09:00
|
|
|
|
)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
crate::box_trait::BoolBox::new(false)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-11 12:09:14 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl BoxCore for ChannelBox {
|
2025-08-09 15:14:44 +09:00
|
|
|
|
fn box_id(&self) -> u64 {
|
2025-08-11 15:01:11 +09:00
|
|
|
|
self.base.id
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn parent_type_id(&self) -> Option<std::any::TypeId> {
|
|
|
|
|
|
self.base.parent_type_id
|
2025-08-11 12:09:14 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn fmt_box(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
|
|
write!(f, "Channel({} >> {})", self.sender_name, self.receiver_name)
|
2025-08-09 15:14:44 +09:00
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
|
|
2025-08-11 15:01:11 +09:00
|
|
|
|
fn as_any(&self) -> &dyn Any {
|
|
|
|
|
|
self
|
|
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
|
|
2025-08-11 15:01:11 +09:00
|
|
|
|
fn as_any_mut(&mut self) -> &mut dyn Any {
|
|
|
|
|
|
self
|
|
|
|
|
|
}
|
2025-08-09 15:14:44 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl Display for ChannelBox {
|
|
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
2025-08-11 12:09:14 +09:00
|
|
|
|
self.fmt_box(f)
|
2025-08-09 15:14:44 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl Debug for ChannelBox {
|
|
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
|
|
f.debug_struct("ChannelBox")
|
|
|
|
|
|
.field("sender_name", &self.sender_name)
|
|
|
|
|
|
.field("receiver_name", &self.receiver_name)
|
2025-08-11 15:01:11 +09:00
|
|
|
|
.field("id", &self.base.id)
|
2025-08-09 15:14:44 +09:00
|
|
|
|
.finish()
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// メッセージを表すBox
|
|
|
|
|
|
#[derive(Debug, Clone)]
|
|
|
|
|
|
pub struct MessageBox {
|
|
|
|
|
|
pub sender: String,
|
|
|
|
|
|
pub content: String,
|
2025-08-11 12:09:14 +09:00
|
|
|
|
base: BoxBase,
|
2025-08-09 15:14:44 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl MessageBox {
|
|
|
|
|
|
pub fn new(sender: &str, content: &str) -> Self {
|
|
|
|
|
|
Self {
|
|
|
|
|
|
sender: sender.to_string(),
|
|
|
|
|
|
content: content.to_string(),
|
2025-08-11 12:09:14 +09:00
|
|
|
|
base: BoxBase::new(),
|
2025-08-09 15:14:44 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl NyashBox for MessageBox {
|
|
|
|
|
|
fn type_name(&self) -> &'static str {
|
|
|
|
|
|
"MessageBox"
|
|
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
|
|
2025-08-09 15:14:44 +09:00
|
|
|
|
fn to_string_box(&self) -> StringBox {
|
2025-09-17 07:43:07 +09:00
|
|
|
|
StringBox::new(&format!(
|
|
|
|
|
|
"[{}] {}: {}",
|
|
|
|
|
|
self.base.id, self.sender, self.content
|
|
|
|
|
|
))
|
2025-08-09 15:14:44 +09:00
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
|
|
2025-08-09 15:14:44 +09:00
|
|
|
|
fn clone_box(&self) -> Box<dyn NyashBox> {
|
|
|
|
|
|
Box::new(self.clone())
|
|
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
|
|
2025-08-15 14:29:47 +09:00
|
|
|
|
/// 仮実装: clone_boxと同じ(後で修正)
|
|
|
|
|
|
fn share_box(&self) -> Box<dyn NyashBox> {
|
|
|
|
|
|
self.clone_box()
|
|
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
|
|
2025-08-09 15:14:44 +09:00
|
|
|
|
fn equals(&self, other: &dyn NyashBox) -> crate::box_trait::BoolBox {
|
|
|
|
|
|
if let Some(other_msg) = other.as_any().downcast_ref::<MessageBox>() {
|
|
|
|
|
|
crate::box_trait::BoolBox::new(
|
2025-09-17 07:43:07 +09:00
|
|
|
|
self.sender == other_msg.sender && self.content == other_msg.content,
|
2025-08-09 15:14:44 +09:00
|
|
|
|
)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
crate::box_trait::BoolBox::new(false)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-08-11 12:09:14 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl BoxCore for MessageBox {
|
2025-08-09 15:14:44 +09:00
|
|
|
|
fn box_id(&self) -> u64 {
|
2025-08-11 15:01:11 +09:00
|
|
|
|
self.base.id
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fn parent_type_id(&self) -> Option<std::any::TypeId> {
|
|
|
|
|
|
self.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-11 15:01:11 +09:00
|
|
|
|
write!(f, "[{}] {}: {}", self.base.id, self.sender, self.content)
|
|
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
|
|
2025-08-11 15:01:11 +09:00
|
|
|
|
fn as_any(&self) -> &dyn Any {
|
|
|
|
|
|
self
|
|
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
|
|
2025-08-11 15:01:11 +09:00
|
|
|
|
fn as_any_mut(&mut self) -> &mut dyn Any {
|
|
|
|
|
|
self
|
2025-08-09 15:14:44 +09:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl Display for MessageBox {
|
|
|
|
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
2025-08-11 12:09:14 +09:00
|
|
|
|
self.fmt_box(f)
|
2025-08-09 15:14:44 +09:00
|
|
|
|
}
|
2025-09-17 07:43:07 +09:00
|
|
|
|
}
|