mqute_codec/protocol/v5/
ping.rs

1//! # Ping Request and Response Packets V5
2//!
3//! This module implements the MQTT PingReq (Ping Request) and PingResp (Ping Response) packets.
4//! These packets are used to maintain the connection between client and server when no other
5//! packets are being sent, and to verify that the connection is still active.
6//!
7//! The PingReq packet is sent by a client to the server to:
8//! 1. Indicate that the client is alive when no other packets are being sent
9//! 2. Verify that the server is available and responding
10//!
11//! The PingResp packet is sent by the server in response to a PingReq to:
12//! 1. Acknowledge the ping request
13//! 2. Confirm that the server is still alive and responsive
14//!
15//! The PingReq and PingResp packet have no payload or variable header - they consist only of a
16//! fixed header.
17
18use super::util;
19use crate::protocol::{PacketType, traits};
20
21/// Represents an MQTT PingReq (Ping Request) packet.
22///
23/// # Example
24///
25/// ```rust
26/// use mqute_codec::protocol::v5::PingReq;
27///
28/// let packet = PingReq { };
29/// ```
30#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
31pub struct PingReq {}
32
33// Implements encoding/decoding using ping packet macros
34util::ping_packet_decode_impl!(PingReq, PacketType::PingReq);
35util::ping_packet_encode_impl!(PingReq, PacketType::PingReq);
36
37impl traits::PingReq for PingReq {}
38
39/// Represents an MQTT PingResp (Ping Response) packet.
40///
41/// # Example
42///
43/// ```rust
44/// use mqute_codec::protocol::v5::PingResp;
45///
46/// let packet = PingResp { };
47/// ```
48#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
49pub struct PingResp {}
50
51// Implements encoding/decoding using ping packet macros
52util::ping_packet_decode_impl!(PingResp, PacketType::PingResp);
53util::ping_packet_encode_impl!(PingResp, PacketType::PingResp);
54
55impl traits::PingResp for PingResp {}
56
57#[cfg(test)]
58mod tests {
59    use super::*;
60    use crate::codec::PacketCodec;
61    use crate::codec::{Decode, Encode};
62    use bytes::BytesMut;
63    use tokio_util::codec::Decoder;
64
65    #[test]
66    fn pingreq_decode() {
67        let mut codec = PacketCodec::new(None, None);
68
69        let data = &[
70            (PacketType::PingReq as u8) << 4, // Packet type
71            0x00,                             // Remaining len
72        ];
73
74        let mut stream = BytesMut::new();
75
76        stream.extend_from_slice(&data[..]);
77
78        let raw_packet = codec.decode(&mut stream).unwrap().unwrap();
79        let packet = PingReq::decode(raw_packet).unwrap();
80
81        assert_eq!(packet, PingReq::default());
82    }
83
84    #[test]
85    fn pingreq_encode() {
86        let packet = PingReq::default();
87
88        let mut stream = BytesMut::new();
89        packet.encode(&mut stream).unwrap();
90        assert_eq!(stream, vec![(PacketType::PingReq as u8) << 4, 0x00]);
91    }
92
93    #[test]
94    fn pingresp_decode() {
95        let mut codec = PacketCodec::new(None, None);
96
97        let data = &[
98            (PacketType::PingResp as u8) << 4, // Packet type
99            0x00,                              // Remaining len
100        ];
101
102        let mut stream = BytesMut::new();
103
104        stream.extend_from_slice(&data[..]);
105
106        let raw_packet = codec.decode(&mut stream).unwrap().unwrap();
107        let packet = PingResp::decode(raw_packet).unwrap();
108
109        assert_eq!(packet, PingResp::default());
110    }
111
112    #[test]
113    fn pingresp_encode() {
114        let packet = PingResp::default();
115
116        let mut stream = BytesMut::new();
117        packet.encode(&mut stream).unwrap();
118        assert_eq!(stream, vec![(PacketType::PingResp as u8) << 4, 0x00]);
119    }
120}