1use glam::{Vec2, Vec3};
4
5use super::PeerId;
6
7#[derive(Debug, Clone, PartialEq)]
10pub enum Arg {
11 Int(i64),
13 Float(f64),
15 Bool(bool),
17 Text(String),
19 Vec2(Vec2),
21 Vec3(Vec3),
23 Bytes(Vec<u8>),
25}
26
27macro_rules! int_args {
28 ($($t:ty),*) => {$(
29 impl From<$t> for Arg {
30 fn from(v: $t) -> Self {
31 Arg::Int(v as i64)
32 }
33 }
34 )*};
35}
36int_args!(i8, i16, i32, i64, u8, u16, u32, u64, usize, isize);
37
38impl From<PeerId> for Arg {
39 fn from(v: PeerId) -> Self {
40 Arg::Int(v.number() as i64)
41 }
42}
43
44impl From<f32> for Arg {
45 fn from(v: f32) -> Self {
46 Arg::Float(v as f64)
47 }
48}
49
50impl From<f64> for Arg {
51 fn from(v: f64) -> Self {
52 Arg::Float(v)
53 }
54}
55
56impl From<bool> for Arg {
57 fn from(v: bool) -> Self {
58 Arg::Bool(v)
59 }
60}
61
62impl From<&str> for Arg {
63 fn from(v: &str) -> Self {
64 Arg::Text(v.to_string())
65 }
66}
67
68impl From<String> for Arg {
69 fn from(v: String) -> Self {
70 Arg::Text(v)
71 }
72}
73
74impl From<&String> for Arg {
75 fn from(v: &String) -> Self {
76 Arg::Text(v.clone())
77 }
78}
79
80impl From<Vec2> for Arg {
81 fn from(v: Vec2) -> Self {
82 Arg::Vec2(v)
83 }
84}
85
86impl From<Vec3> for Arg {
87 fn from(v: Vec3) -> Self {
88 Arg::Vec3(v)
89 }
90}
91
92impl From<Vec<u8>> for Arg {
93 fn from(v: Vec<u8>) -> Self {
94 Arg::Bytes(v)
95 }
96}
97
98impl From<&[u8]> for Arg {
99 fn from(v: &[u8]) -> Self {
100 Arg::Bytes(v.to_vec())
101 }
102}
103
104#[derive(Debug, Clone, PartialEq, Default)]
120pub struct Packet {
121 kind: String,
122 args: Vec<Arg>,
123}
124
125impl Packet {
126 pub fn new(kind: impl Into<String>) -> Self {
128 Self { kind: kind.into(), args: Vec::new() }
129 }
130
131 pub fn with(mut self, value: impl Into<Arg>) -> Self {
133 self.args.push(value.into());
134 self
135 }
136
137 pub fn push(&mut self, value: impl Into<Arg>) {
139 self.args.push(value.into());
140 }
141
142 pub fn kind(&self) -> &str {
144 &self.kind
145 }
146
147 pub fn is(&self, kind: &str) -> bool {
149 self.kind == kind
150 }
151
152 pub fn args(&self) -> &[Arg] {
154 &self.args
155 }
156
157 pub fn len(&self) -> usize {
159 self.args.len()
160 }
161
162 pub fn is_empty(&self) -> bool {
164 self.args.is_empty()
165 }
166
167 pub fn get(&self, index: usize) -> Option<&Arg> {
169 self.args.get(index)
170 }
171
172 pub fn int(&self, index: usize) -> i64 {
175 match self.get(index) {
176 Some(Arg::Int(v)) => *v,
177 Some(Arg::Float(v)) => *v as i64,
178 Some(Arg::Bool(v)) => *v as i64,
179 Some(Arg::Text(v)) => v.trim().parse().unwrap_or(0),
180 _ => 0,
181 }
182 }
183
184 pub fn float(&self, index: usize) -> f32 {
187 match self.get(index) {
188 Some(Arg::Int(v)) => *v as f32,
189 Some(Arg::Float(v)) => *v as f32,
190 Some(Arg::Bool(v)) => *v as u8 as f32,
191 Some(Arg::Text(v)) => v.trim().parse().unwrap_or(0.0),
192 _ => 0.0,
193 }
194 }
195
196 pub fn bool(&self, index: usize) -> bool {
199 match self.get(index) {
200 Some(Arg::Bool(v)) => *v,
201 Some(Arg::Int(v)) => *v != 0,
202 Some(Arg::Float(v)) => *v != 0.0,
203 Some(Arg::Text(v)) => v.trim() == "true",
204 _ => false,
205 }
206 }
207
208 pub fn text(&self, index: usize) -> &str {
210 match self.get(index) {
211 Some(Arg::Text(v)) => v,
212 _ => "",
213 }
214 }
215
216 pub fn vec2(&self, index: usize) -> Vec2 {
219 match self.get(index) {
220 Some(Arg::Vec2(v)) => *v,
221 Some(Arg::Vec3(v)) => v.truncate(),
222 _ => Vec2::ZERO,
223 }
224 }
225
226 pub fn vec3(&self, index: usize) -> Vec3 {
229 match self.get(index) {
230 Some(Arg::Vec3(v)) => *v,
231 Some(Arg::Vec2(v)) => v.extend(0.0),
232 _ => Vec3::ZERO,
233 }
234 }
235
236 pub fn peer(&self, index: usize) -> PeerId {
239 PeerId::from_number(u32::try_from(self.int(index)).unwrap_or(0))
240 }
241
242 pub fn bytes(&self, index: usize) -> &[u8] {
244 match self.get(index) {
245 Some(Arg::Bytes(v)) => v,
246 _ => &[],
247 }
248 }
249
250 pub(crate) fn encode(&self, out: &mut Vec<u8>) {
251 put_str(out, &self.kind);
252 out.extend_from_slice(&(self.args.len() as u32).to_le_bytes());
253 for arg in &self.args {
254 match arg {
255 Arg::Int(v) => {
256 out.push(0);
257 out.extend_from_slice(&v.to_le_bytes());
258 }
259 Arg::Float(v) => {
260 out.push(1);
261 out.extend_from_slice(&v.to_le_bytes());
262 }
263 Arg::Bool(v) => {
264 out.push(2);
265 out.push(*v as u8);
266 }
267 Arg::Text(v) => {
268 out.push(3);
269 put_str(out, v);
270 }
271 Arg::Vec2(v) => {
272 out.push(4);
273 for c in v.to_array() {
274 out.extend_from_slice(&c.to_le_bytes());
275 }
276 }
277 Arg::Vec3(v) => {
278 out.push(5);
279 for c in v.to_array() {
280 out.extend_from_slice(&c.to_le_bytes());
281 }
282 }
283 Arg::Bytes(v) => {
284 out.push(6);
285 put_bytes(out, v);
286 }
287 }
288 }
289 }
290
291 pub(crate) fn decode(r: &mut Reader) -> Option<Self> {
292 let kind = r.str()?;
293 let count = r.u32()? as usize;
294 if count > r.remaining() / 2 {
296 return None;
297 }
298 let mut args = Vec::with_capacity(count);
299 for _ in 0..count {
300 args.push(match r.u8()? {
301 0 => Arg::Int(i64::from_le_bytes(r.array()?)),
302 1 => Arg::Float(f64::from_le_bytes(r.array()?)),
303 2 => Arg::Bool(r.u8()? != 0),
304 3 => Arg::Text(r.str()?),
305 4 => Arg::Vec2(Vec2::new(r.f32()?, r.f32()?)),
306 5 => Arg::Vec3(Vec3::new(r.f32()?, r.f32()?, r.f32()?)),
307 6 => Arg::Bytes(r.bytes()?.to_vec()),
308 _ => return None,
309 });
310 }
311 Some(Self { kind, args })
312 }
313}
314
315impl From<&str> for Packet {
316 fn from(kind: &str) -> Self {
317 Packet::new(kind)
318 }
319}
320
321impl From<String> for Packet {
322 fn from(kind: String) -> Self {
323 Packet::new(kind)
324 }
325}
326
327impl From<&Packet> for Packet {
328 fn from(packet: &Packet) -> Self {
329 packet.clone()
330 }
331}
332
333pub(crate) fn put_bytes(out: &mut Vec<u8>, bytes: &[u8]) {
334 out.extend_from_slice(&(bytes.len() as u32).to_le_bytes());
335 out.extend_from_slice(bytes);
336}
337
338pub(crate) fn put_str(out: &mut Vec<u8>, text: &str) {
339 put_bytes(out, text.as_bytes());
340}
341
342pub(crate) struct Reader<'a> {
344 data: &'a [u8],
345}
346
347impl<'a> Reader<'a> {
348 pub(crate) fn new(data: &'a [u8]) -> Self {
349 Self { data }
350 }
351
352 pub(crate) fn remaining(&self) -> usize {
353 self.data.len()
354 }
355
356 fn take(&mut self, n: usize) -> Option<&'a [u8]> {
357 if n > self.data.len() {
358 return None;
359 }
360 let (head, tail) = self.data.split_at(n);
361 self.data = tail;
362 Some(head)
363 }
364
365 fn array<const N: usize>(&mut self) -> Option<[u8; N]> {
366 self.take(N)?.try_into().ok()
367 }
368
369 pub(crate) fn u8(&mut self) -> Option<u8> {
370 Some(self.take(1)?[0])
371 }
372
373 pub(crate) fn u16(&mut self) -> Option<u16> {
374 Some(u16::from_le_bytes(self.array()?))
375 }
376
377 pub(crate) fn u32(&mut self) -> Option<u32> {
378 Some(u32::from_le_bytes(self.array()?))
379 }
380
381 pub(crate) fn u64(&mut self) -> Option<u64> {
382 Some(u64::from_le_bytes(self.array()?))
383 }
384
385 fn f32(&mut self) -> Option<f32> {
386 Some(f32::from_le_bytes(self.array()?))
387 }
388
389 pub(crate) fn bytes(&mut self) -> Option<&'a [u8]> {
390 let len = self.u32()? as usize;
391 self.take(len)
392 }
393
394 pub(crate) fn str(&mut self) -> Option<String> {
395 Some(String::from_utf8_lossy(self.bytes()?).into_owned())
396 }
397}
398
399#[cfg(test)]
400mod tests {
401 use super::*;
402
403 #[test]
404 fn round_trip() {
405 let packet = Packet::new("all")
406 .with(-5)
407 .with(2.5)
408 .with(true)
409 .with("hä?")
410 .with(Vec2::new(1.0, 2.0))
411 .with(Vec3::new(1.0, 2.0, 3.0))
412 .with(vec![1u8, 2, 3]);
413 let mut bytes = Vec::new();
414 packet.encode(&mut bytes);
415 let decoded = Packet::decode(&mut Reader::new(&bytes)).unwrap();
416 assert_eq!(decoded, packet);
417 assert!(Packet::decode(&mut Reader::new(&bytes[..bytes.len() - 1])).is_none());
418 }
419
420 #[test]
421 fn lenient_getters() {
422 let p = Packet::new("x").with(3).with("4.5").with(Vec2::new(1.0, 2.0));
423 assert_eq!(p.float(0), 3.0);
424 assert_eq!(p.float(1), 4.5);
425 assert_eq!(p.int(1), 0);
426 assert_eq!(p.text(0), "");
427 assert_eq!(p.vec3(2), Vec3::new(1.0, 2.0, 0.0));
428 assert!(p.bool(0));
429 assert!(!p.bool(9));
430 }
431}