roplat 0.2.0

roplat: just a robot operation system
Documentation
//! 握手协议
//!
//! 订阅者连接到发布者后发送 `Hello`,发布者验证 `SchemaId` / `msg_version` / `role`
//! 后回 `HelloAck`。任一侧不匹配立即断开,避免数据层混流。
//!
//! 报文用 JSON 编码;握手发生一次,性能不敏感,优先选择可读性以便诊断。

use super::endpoint::{Role, SchemaId};
use serde::{Deserialize, Serialize};

/// Handshake request message.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Hello {
    /// 固定 "roplat-ipc"
    pub magic: String,
    /// 协议版本,MVP = 1
    pub protocol_version: u16,
    /// 发起方角色
    pub role: Role,
    /// 发起方的 schema 指纹
    pub schema_id: SchemaId,
    /// 发起方的消息版本
    pub msg_version: u16,
    /// 端点名 `<namespace>/<name>`,仅作为诊断信息
    pub endpoint: String,
}

impl Hello {
    /// Protocol magic constant.
    pub const MAGIC: &'static str = "roplat-ipc";
    /// Protocol version constant.
    pub const PROTOCOL_VERSION: u16 = 1;

    /// Constructs a handshake request.
    pub fn new(
        role: Role,
        schema_id: SchemaId,
        msg_version: u16,
        endpoint: impl Into<String>,
    ) -> Self {
        Self {
            magic: Self::MAGIC.to_string(),
            protocol_version: Self::PROTOCOL_VERSION,
            role,
            schema_id,
            msg_version,
            endpoint: endpoint.into(),
        }
    }
}

/// Handshake response message.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct HelloAck {
    /// Protocol magic.
    pub magic: String,
    /// Protocol version.
    pub protocol_version: u16,
    /// Whether the connection is accepted.
    pub accepted: bool,
    /// 被拒理由(接受时为 None)
    pub reason: Option<String>,
}

impl HelloAck {
    /// Constructs an accepted response.
    pub fn ok() -> Self {
        Self {
            magic: Hello::MAGIC.to_string(),
            protocol_version: Hello::PROTOCOL_VERSION,
            accepted: true,
            reason: None,
        }
    }

    /// Constructs a rejected response with reason.
    pub fn reject(reason: impl Into<String>) -> Self {
        Self {
            magic: Hello::MAGIC.to_string(),
            protocol_version: Hello::PROTOCOL_VERSION,
            accepted: false,
            reason: Some(reason.into()),
        }
    }
}