1use crate::multiplex::{
34 read_varuint_slice, CLIENT_POLL_SERVER, CLIENT_POLL_SERVER_FLOW, CLIENT_TO_SERVER,
35 SERVER_TO_CLIENT, SERVER_TO_CLIENT_FLOW,
36};
37
38pub const MAX_WRITE: usize = 61;
42
43pub fn write_client_to_server(channel: u8, data: &[u8], out: &mut [u8; 64]) -> u8 {
50 assert!(data.len() <= MAX_WRITE);
51
52 out[0] = CLIENT_TO_SERVER;
53 out[1] = channel;
54 out[2] = data.len() as u8;
55 out[3..3 + data.len()].copy_from_slice(data);
56 (3 + data.len()) as u8
57}
58
59pub fn write_client_poll(channel: u8, max_length: u8, out: &mut [u8; 64]) -> u8 {
62 out[0] = CLIENT_POLL_SERVER;
63 out[1] = channel;
64 out[2] = max_length;
65 3
66}
67
68pub fn write_client_poll_flow(
75 channel: u8,
76 packet_number: u8,
77 max_length: u8,
78 out: &mut [u8; 64],
79) -> u8 {
80 out[0] = CLIENT_POLL_SERVER_FLOW;
81 out[1] = channel;
82 out[2] = packet_number;
83 out[3] = max_length;
84 4
85}
86
87pub fn parse_server_to_client(payload: &[u8], channel: u8) -> Option<&[u8]> {
90 let (action, rest) = payload.split_first()?;
91 if *action != SERVER_TO_CLIENT {
92 return None;
93 }
94 let (msg_channel, rest) = rest.split_first()?;
95 if *msg_channel != channel {
96 return None;
97 }
98 let (len, rest) = read_varuint_slice(rest)?;
99 rest.get(..len as usize)
100}
101
102#[derive(Debug, Clone, Copy, PartialEq, Eq)]
104pub struct FlowData<'a> {
105 pub packet_number: u8,
108 pub data: &'a [u8],
110}
111
112pub fn parse_server_to_client_flow(payload: &[u8], channel: u8) -> Option<FlowData<'_>> {
117 let (action, rest) = payload.split_first()?;
118 if *action != SERVER_TO_CLIENT_FLOW {
119 return None;
120 }
121 let (msg_channel, rest) = rest.split_first()?;
122 if *msg_channel != channel {
123 return None;
124 }
125 let (packet_number, rest) = rest.split_first()?;
126 let (len, rest) = read_varuint_slice(rest)?;
127 Some(FlowData {
128 packet_number: *packet_number,
129 data: rest.get(..len as usize)?,
130 })
131}
132
133#[cfg(test)]
134mod tests {
135 use super::*;
136
137 #[test]
138 fn test_write_client_to_server() {
139 let mut out = [0u8; 64];
140 let size = write_client_to_server(1, b"hello", &mut out);
141 assert_eq!(size, 8);
142 assert_eq!(&out[..8], &[0x40, 0x01, 0x05, b'h', b'e', b'l', b'l', b'o']);
143 }
144
145 #[test]
146 fn test_write_client_poll() {
147 let mut out = [0u8; 64];
148 let size = write_client_poll(1, 48, &mut out);
149 assert_eq!(size, 3);
150 assert_eq!(&out[..3], &[0x42, 0x01, 0x30]);
151 }
152
153 #[test]
154 fn test_write_client_poll_flow() {
155 let mut out = [0u8; 64];
158 let size = write_client_poll_flow(1, 0xAB, 48, &mut out);
159 assert_eq!(size, 4);
160 assert_eq!(&out[..4], &[0x44, 0x01, 0xAB, 0x30]);
161 }
162
163 #[test]
164 fn test_parse_server_to_client() {
165 assert_eq!(
166 parse_server_to_client(&[0x41, 0x01, 0x03, b'a', b'b', b'c'], 1),
167 Some(b"abc".as_slice())
168 );
169
170 assert_eq!(
172 parse_server_to_client(&[0x41, 0x01, 0x00], 1),
173 Some(b"".as_slice())
174 );
175
176 assert_eq!(parse_server_to_client(&[0x41, 0x02, 0x01, b'a'], 1), None);
178 assert_eq!(parse_server_to_client(&[0x43, 0x01, 0x01, b'a'], 1), None);
179 assert_eq!(parse_server_to_client(&[0x41, 0x01, 0x05, b'a'], 1), None);
180 assert_eq!(parse_server_to_client(&[], 1), None);
181 }
182
183 #[test]
184 fn test_parse_server_to_client_flow() {
185 let result =
186 parse_server_to_client_flow(&[0x43, 0x01, 0x07, 0x03, b'a', b'b', b'c'], 1).unwrap();
187 assert_eq!(result.packet_number, 0x07);
188 assert_eq!(result.data, b"abc");
189
190 let result = parse_server_to_client_flow(&[0x43, 0x01, 0xFF, 0x00], 1).unwrap();
192 assert_eq!(result.packet_number, 0xFF);
193 assert_eq!(result.data, b"");
194
195 assert_eq!(
197 parse_server_to_client_flow(&[0x41, 0x01, 0x01, b'a'], 1),
198 None
199 );
200 assert_eq!(
202 parse_server_to_client_flow(&[0x43, 0x02, 0x07, 0x00], 1),
203 None
204 );
205 assert_eq!(parse_server_to_client_flow(&[0x43, 0x01, 0x07], 1), None);
207 assert_eq!(
208 parse_server_to_client_flow(&[0x43, 0x01, 0x07, 0x05, b'a'], 1),
209 None
210 );
211 }
212
213 #[test]
214 fn test_round_trip_via_write_combiner_sizes() {
215 let mut out = [0u8; 64];
217 let size = write_client_poll_flow(2, 5, 10, &mut out) as usize;
218 assert_eq!(&out[..size], &[0x44, 0x02, 0x05, 0x0A]);
219
220 let response = [0x43, 0x02, 0x06, 0x02, 0x11, 0x22];
221 let parsed = parse_server_to_client_flow(&response, 2).unwrap();
222 assert_eq!(parsed.packet_number, 6);
223 assert_eq!(parsed.data, &[0x11, 0x22]);
224 }
225
226 #[test]
227 fn test_read_varuint_multibyte() {
228 let (value, rest) = read_varuint_slice(&[0x80, 0x01, 0xAA]).unwrap();
230 assert_eq!(value, 128);
231 assert_eq!(rest, &[0xAA]);
232
233 assert!(read_varuint_slice(&[0x80, 0x80, 0x80, 0x80, 0x80]).is_none());
235 }
236}