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(str::to_owned),
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: impl Into<String>, data: Option<Vec<u8>>) -> Self {
69 Self {
70 data,
71 key: Some(event.into()),
72 r#type: WsIoPacketType::Event,
73 }
74 }
75
76 #[inline]
77 pub fn new_init(data: Option<Vec<u8>>) -> Self {
78 Self::new(WsIoPacketType::Init, None, data)
79 }
80
81 #[inline]
82 pub fn new_ready() -> Self {
83 Self::new(WsIoPacketType::Ready, None, None)
84 }
85}
86
87#[cfg(test)]
88mod tests {
89 use super::*;
90
91 #[test]
92 fn test_new_packet_constructors() {
93 let packet = WsIoPacket::new_disconnect();
95 assert!(matches!(packet.r#type, WsIoPacketType::Disconnect));
96 assert_eq!(packet.key, None);
97 assert_eq!(packet.data, None);
98
99 let packet = WsIoPacket::new_event("chat", None);
101 assert!(matches!(packet.r#type, WsIoPacketType::Event));
102 assert_eq!(packet.key.as_deref(), Some("chat"));
103 assert_eq!(packet.data, None);
104
105 let packet = WsIoPacket::new_event("chat", Some(vec![1, 2, 3]));
107 assert!(matches!(packet.r#type, WsIoPacketType::Event));
108 assert_eq!(packet.key.as_deref(), Some("chat"));
109 assert_eq!(packet.data.as_deref(), Some(&[1, 2, 3][..]));
110
111 let packet = WsIoPacket::new_init(Some(vec![4, 5, 6]));
113 assert!(matches!(packet.r#type, WsIoPacketType::Init));
114 assert_eq!(packet.key, None);
115 assert_eq!(packet.data.as_deref(), Some(&[4, 5, 6][..]));
116
117 let packet = WsIoPacket::new_ready();
119 assert!(matches!(packet.r#type, WsIoPacketType::Ready));
120 assert_eq!(packet.key, None);
121 assert_eq!(packet.data, None);
122 }
123}