1use serde::{
2 Deserialize,
3 Serialize,
4};
5use serde_repr::{
6 Deserialize_repr,
7 Serialize_repr,
8};
9
10pub mod codecs;
11
12#[repr(u8)]
14#[derive(Clone, Debug, Deserialize_repr, Serialize_repr)]
15pub enum WsIoPacketType {
16 Disconnect = 0,
17 Event = 1,
18 Init = 2,
19 Ready = 3,
20}
21
22#[derive(Deserialize)]
24struct InnerPacket(WsIoPacketType, Option<String>, Option<Vec<u8>>);
25
26#[derive(Serialize)]
27struct InnerPacketRef<'a>(&'a WsIoPacketType, &'a Option<String>, &'a Option<Vec<u8>>);
28
29#[derive(Clone, Debug)]
30pub struct WsIoPacket {
31 pub data: Option<Vec<u8>>,
32 pub key: Option<String>,
33 pub r#type: WsIoPacketType,
34}
35
36impl WsIoPacket {
37 #[inline]
38 pub fn new(r#type: WsIoPacketType, key: Option<&str>, data: Option<Vec<u8>>) -> Self {
39 Self {
40 data,
41 key: key.map(|k| k.into()),
42 r#type,
43 }
44 }
45
46 #[inline]
48 pub(self) fn from_inner(inner: InnerPacket) -> Self {
49 Self {
50 data: inner.2,
51 key: inner.1,
52 r#type: inner.0,
53 }
54 }
55
56 #[inline]
57 pub(self) fn to_inner_ref(&self) -> InnerPacketRef<'_> {
58 InnerPacketRef(&self.r#type, &self.key, &self.data)
59 }
60
61 #[inline]
63 pub fn new_disconnect() -> Self {
64 Self::new(WsIoPacketType::Disconnect, None, None)
65 }
66
67 #[inline]
68 pub fn new_event(event: &str, data: Option<Vec<u8>>) -> Self {
69 Self::new(WsIoPacketType::Event, Some(event), data)
70 }
71
72 #[inline]
73 pub fn new_init(data: Option<Vec<u8>>) -> Self {
74 Self::new(WsIoPacketType::Init, None, data)
75 }
76
77 #[inline]
78 pub fn new_ready() -> Self {
79 Self::new(WsIoPacketType::Ready, None, None)
80 }
81}
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86
87 #[test]
88 fn test_new_packet_constructors() {
89 let packet = WsIoPacket::new_disconnect();
91 assert!(matches!(packet.r#type, WsIoPacketType::Disconnect));
92 assert_eq!(packet.key, None);
93 assert_eq!(packet.data, None);
94
95 let packet = WsIoPacket::new_event("chat", None);
97 assert!(matches!(packet.r#type, WsIoPacketType::Event));
98 assert_eq!(packet.key.as_deref(), Some("chat"));
99 assert_eq!(packet.data, None);
100
101 let packet = WsIoPacket::new_event("chat", Some(vec![1, 2, 3]));
103 assert!(matches!(packet.r#type, WsIoPacketType::Event));
104 assert_eq!(packet.key.as_deref(), Some("chat"));
105 assert_eq!(packet.data.as_deref(), Some(&[1, 2, 3][..]));
106
107 let packet = WsIoPacket::new_init(Some(vec![4, 5, 6]));
109 assert!(matches!(packet.r#type, WsIoPacketType::Init));
110 assert_eq!(packet.key, None);
111 assert_eq!(packet.data.as_deref(), Some(&[4, 5, 6][..]));
112
113 let packet = WsIoPacket::new_ready();
115 assert!(matches!(packet.r#type, WsIoPacketType::Ready));
116 assert_eq!(packet.key, None);
117 assert_eq!(packet.data, None);
118 }
119}