rpcnet 0.1.0

RPC library based on QUIC+TLS encryption
Documentation
use crate::cluster::gossip::{NodeId, NodeUpdate};
use serde::{Deserialize, Serialize};
use std::net::SocketAddr;

#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SwimMessage {
    Ping {
        from: NodeId,
        from_addr: SocketAddr,
        updates: Vec<NodeUpdate>,
        seq: u64,
    },
    Ack {
        from: NodeId,
        to: NodeId,
        updates: Vec<NodeUpdate>,
        seq: u64,
    },
    PingReq {
        from: NodeId,
        target: SocketAddr,
        target_id: NodeId,
        updates: Vec<NodeUpdate>,
        seq: u64,
    },
}

impl SwimMessage {
    pub fn seq(&self) -> u64 {
        match self {
            SwimMessage::Ping { seq, .. } => *seq,
            SwimMessage::Ack { seq, .. } => *seq,
            SwimMessage::PingReq { seq, .. } => *seq,
        }
    }

    pub fn from_node(&self) -> &NodeId {
        match self {
            SwimMessage::Ping { from, .. } => from,
            SwimMessage::Ack { from, .. } => from,
            SwimMessage::PingReq { from, .. } => from,
        }
    }

    pub fn updates(&self) -> &[NodeUpdate] {
        match self {
            SwimMessage::Ping { updates, .. } => updates,
            SwimMessage::Ack { updates, .. } => updates,
            SwimMessage::PingReq { updates, .. } => updates,
        }
    }

    pub fn serialize(&self) -> Result<Vec<u8>, Box<bincode::ErrorKind>> {
        bincode::serialize(self)
    }

    pub fn deserialize(bytes: &[u8]) -> Result<Self, Box<bincode::ErrorKind>> {
        bincode::deserialize(bytes)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_ping_serialization() {
        let ping = SwimMessage::Ping {
            from: NodeId::new("node-1"),
            from_addr: "127.0.0.1:8000".parse().unwrap(),
            updates: vec![],
            seq: 42,
        };

        let bytes = ping.serialize().unwrap();
        let deserialized = SwimMessage::deserialize(&bytes).unwrap();

        assert_eq!(ping.seq(), deserialized.seq());
        assert_eq!(ping.from_node().as_str(), "node-1");
    }

    #[test]
    fn test_ack_serialization() {
        let ack = SwimMessage::Ack {
            from: NodeId::new("node-2"),
            to: NodeId::new("node-1"),
            updates: vec![],
            seq: 100,
        };

        let bytes = ack.serialize().unwrap();
        let deserialized = SwimMessage::deserialize(&bytes).unwrap();

        assert_eq!(deserialized.seq(), 100);
    }

    #[test]
    fn test_ping_req_serialization() {
        let ping_req = SwimMessage::PingReq {
            from: NodeId::new("node-1"),
            target: "127.0.0.1:8002".parse().unwrap(),
            target_id: NodeId::new("node-3"),
            updates: vec![],
            seq: 200,
        };

        let bytes = ping_req.serialize().unwrap();
        let deserialized = SwimMessage::deserialize(&bytes).unwrap();

        assert_eq!(deserialized.seq(), 200);
    }
}