use bytes::{Buf, BufMut};
use crate::types::{self, ProtocolError};
use super::Packet;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StatusRequestPacket;
impl Packet for StatusRequestPacket {
const PACKET_ID: i32 = 0x00;
fn decode(_buf: &mut impl Buf) -> Result<Self, ProtocolError> {
Ok(Self)
}
fn encode(&self, _buf: &mut impl BufMut) {}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StatusResponsePacket {
pub json: String,
}
impl Packet for StatusResponsePacket {
const PACKET_ID: i32 = 0x00;
fn decode(buf: &mut impl Buf) -> Result<Self, ProtocolError> {
let json = types::read_string(buf)?;
Ok(Self { json })
}
fn encode(&self, buf: &mut impl BufMut) {
types::write_string(buf, &self.json);
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PingRequestPacket {
pub payload: i64,
}
impl Packet for PingRequestPacket {
const PACKET_ID: i32 = 0x01;
fn decode(buf: &mut impl Buf) -> Result<Self, ProtocolError> {
if buf.remaining() < 8 {
return Err(ProtocolError::UnexpectedEof);
}
Ok(Self {
payload: buf.get_i64(),
})
}
fn encode(&self, buf: &mut impl BufMut) {
buf.put_i64(self.payload);
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PongResponsePacket {
pub payload: i64,
}
impl Packet for PongResponsePacket {
const PACKET_ID: i32 = 0x01;
fn decode(buf: &mut impl Buf) -> Result<Self, ProtocolError> {
if buf.remaining() < 8 {
return Err(ProtocolError::UnexpectedEof);
}
Ok(Self {
payload: buf.get_i64(),
})
}
fn encode(&self, buf: &mut impl BufMut) {
buf.put_i64(self.payload);
}
}
#[cfg(test)]
mod tests {
use super::*;
use proptest::prelude::*;
proptest! {
#[test]
fn status_request_roundtrip(packet in Just(StatusRequestPacket)) {
let mut buf = Vec::new();
packet.encode(&mut buf);
let decoded = StatusRequestPacket::decode(&mut &buf[..]).unwrap();
prop_assert_eq!(decoded, packet);
}
#[test]
fn status_response_roundtrip(json in any::<String>()) {
let json = if json.len() > 1024 { json[..1024].to_string() } else { json };
let packet = StatusResponsePacket { json };
let mut buf = Vec::new();
packet.encode(&mut buf);
let decoded = StatusResponsePacket::decode(&mut &buf[..]).unwrap();
prop_assert_eq!(decoded, packet);
}
#[test]
fn ping_request_roundtrip(payload in any::<i64>()) {
let packet = PingRequestPacket { payload };
let mut buf = Vec::new();
packet.encode(&mut buf);
let decoded = PingRequestPacket::decode(&mut &buf[..]).unwrap();
prop_assert_eq!(decoded, packet);
}
#[test]
fn pong_response_roundtrip(payload in any::<i64>()) {
let packet = PongResponsePacket { payload };
let mut buf = Vec::new();
packet.encode(&mut buf);
let decoded = PongResponsePacket::decode(&mut &buf[..]).unwrap();
prop_assert_eq!(decoded, packet);
}
}
}