use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use uuid::Uuid;
pub type PeerId = String;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct PeerCapability {
pub name: String,
#[serde(default)]
pub version: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum PeerMessage {
Hello {
from: PeerId,
capabilities: Vec<PeerCapability>,
},
Broadcast {
from: PeerId,
topic: String,
payload: serde_json::Value,
},
Direct {
from: PeerId,
to: PeerId,
payload: serde_json::Value,
},
Task {
from: PeerId,
task_id: String,
spec: serde_json::Value,
issued_at: DateTime<Utc>,
},
Result {
from: PeerId,
task_id: String,
result: serde_json::Value,
ok: bool,
},
}
impl PeerMessage {
pub fn sender(&self) -> &PeerId {
match self {
PeerMessage::Hello { from, .. }
| PeerMessage::Broadcast { from, .. }
| PeerMessage::Direct { from, .. }
| PeerMessage::Task { from, .. }
| PeerMessage::Result { from, .. } => from,
}
}
pub fn broadcast(
from: impl Into<PeerId>,
topic: impl Into<String>,
payload: serde_json::Value,
) -> Self {
Self::Broadcast {
from: from.into(),
topic: topic.into(),
payload,
}
}
pub fn direct(
from: impl Into<PeerId>,
to: impl Into<PeerId>,
payload: serde_json::Value,
) -> Self {
Self::Direct {
from: from.into(),
to: to.into(),
payload,
}
}
pub fn task(from: impl Into<PeerId>, spec: serde_json::Value) -> Self {
Self::Task {
from: from.into(),
task_id: Uuid::new_v4().to_string(),
spec,
issued_at: Utc::now(),
}
}
}