1mod primitives;
2
3pub use primitives::*;
4pub use voidmc_codec_macros::{Decode, Encode};
5
6pub trait Encode {
7 fn encode(&self, buf: &mut Vec<u8>);
8}
9
10pub trait Decode: Sized {
11 fn decode(buf: &mut &[u8]) -> Result<Self, DecodeError>;
12}
13
14#[derive(Debug, Clone, PartialEq, Eq)]
15pub enum DecodeError {
16 UnexpectedEof,
17 InvalidVarintLength,
18 InvalidPacketId(Option<u8>),
19 InvalidLength,
20}
21
22impl std::fmt::Display for DecodeError {
23 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24 match self {
25 DecodeError::UnexpectedEof => write!(f, "Unexpected end of stream"),
26 DecodeError::InvalidVarintLength => write!(f, "Invalid variable-length integer"),
27 DecodeError::InvalidPacketId(Some(id)) => {
28 write!(f, "Unsupported packet id 0x{:02X}", id)
29 }
30 DecodeError::InvalidPacketId(None) => write!(f, "Invalid packet id"),
31 DecodeError::InvalidLength => write!(f, "Invalid length value"),
32 }
33 }
34}
35
36impl std::error::Error for DecodeError {}
37
38#[cfg(test)]
39mod tests {
40 use super::*;
41 use crate as voidmc_codec;
42
43 #[test]
44 fn test_struct_with_mixed_fields() {
45 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
46 pub struct TestPacket {
47 pub a: u8,
48 pub b: i32,
49 pub c: bool,
50 }
51
52 let packet = TestPacket {
53 a: 42,
54 b: 12345,
55 c: true,
56 };
57
58 let mut buf = Vec::new();
59 packet.encode(&mut buf);
60
61 let mut slice = buf.as_slice();
62 let decoded = TestPacket::decode(&mut slice).unwrap();
63
64 assert_eq!(decoded, packet);
65 assert_eq!(slice.len(), 0);
66 }
67
68 #[test]
69 fn test_struct_with_vari32() {
70 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
71 pub struct VarPacket {
72 pub prefix: u8,
73 #[codec(varint32)]
74 pub value: i32,
75 }
76
77 let packet = VarPacket {
78 prefix: 1,
79 value: 12345,
80 };
81
82 let mut buf = Vec::new();
83 packet.encode(&mut buf);
84
85 let mut slice = buf.as_slice();
86 let decoded = VarPacket::decode(&mut slice).unwrap();
87
88 assert_eq!(decoded, packet);
89 assert_eq!(slice.len(), 0);
90 }
91
92 #[test]
93 fn test_struct_with_vari32_compression() {
94 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
95 pub struct SmallVarPacket {
96 #[codec(varint32)]
97 pub value: i32,
98 }
99
100 let packet = SmallVarPacket { value: 100 };
101
102 let mut buf = Vec::new();
103 packet.encode(&mut buf);
104
105 let small_vari_size = buf.len();
106
107 let packet2 = SmallVarPacket { value: i32::MAX };
108
109 let mut buf2 = Vec::new();
110 packet2.encode(&mut buf2);
111
112 let large_vari_size = buf2.len();
113
114 assert!(small_vari_size < large_vari_size);
115 assert_eq!(small_vari_size, 1);
116 assert_eq!(large_vari_size, 5);
117 }
118
119 #[test]
120 fn test_tagged_enum() {
121 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
122 pub struct Packet1 {
123 pub data: u8,
124 }
125
126 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
127 pub struct Packet2 {
128 pub value: i32,
129 }
130
131 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode)]
132 #[codec(tagged)]
133 pub enum StatePacket {
134 #[codec(packet_id = 0)]
135 First(Packet1),
136 #[codec(packet_id = 1)]
137 Second(Packet2),
138 }
139
140 let packet = StatePacket::First(Packet1 { data: 42 });
141
142 let mut buf = Vec::new();
143 packet.encode(&mut buf);
144
145 assert_eq!(buf[0], 0);
146
147 let mut slice = buf.as_slice();
148 let decoded = StatePacket::decode(&mut slice).unwrap();
149
150 match decoded {
151 StatePacket::First(p) => assert_eq!(p.data, 42),
152 _ => panic!("Wrong variant"),
153 }
154 }
155
156 #[test]
157 fn test_tagged_enum_second_variant() {
158 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
159 pub struct Packet1 {
160 pub data: u8,
161 }
162
163 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
164 pub struct Packet2 {
165 pub value: i32,
166 }
167
168 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode)]
169 #[codec(tagged)]
170 pub enum StatePacket {
171 #[codec(packet_id = 0)]
172 First(Packet1),
173 #[codec(packet_id = 1)]
174 Second(Packet2),
175 }
176
177 let packet = StatePacket::Second(Packet2 { value: 12345 });
178
179 let mut buf = Vec::new();
180 packet.encode(&mut buf);
181
182 assert_eq!(buf[0], 1);
183
184 let mut slice = buf.as_slice();
185 let decoded = StatePacket::decode(&mut slice).unwrap();
186
187 match decoded {
188 StatePacket::Second(p) => assert_eq!(p.value, 12345),
189 _ => panic!("Wrong variant"),
190 }
191 }
192
193 #[test]
194 fn test_tagged_enum_invalid_id() {
195 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, Debug, PartialEq)]
196 #[codec(tagged)]
197 pub enum StatePacket {
198 #[codec(packet_id = 0)]
199 First(u8),
200 }
201
202 let buf = vec![255];
203 let mut slice = buf.as_slice();
204 let result = StatePacket::decode(&mut slice);
205
206 assert_eq!(result, Err(DecodeError::InvalidPacketId(Some(255))));
207 }
208
209 #[test]
210 fn test_unit_struct() {
211 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
212 pub struct UnitPacket;
213
214 let packet = UnitPacket;
215
216 let mut buf = Vec::new();
217 packet.encode(&mut buf);
218
219 assert_eq!(buf.len(), 0);
220
221 let mut slice = buf.as_slice();
222 let decoded = UnitPacket::decode(&mut slice).unwrap();
223
224 assert_eq!(decoded, packet);
225 }
226
227 #[test]
228 fn test_empty_decode() {
229 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
230 pub struct TestPacket {
231 pub a: i32,
232 }
233
234 let mut slice = &[][..];
235 let result = TestPacket::decode(&mut slice);
236
237 assert_eq!(result, Err(DecodeError::UnexpectedEof));
238 }
239
240 #[test]
241 fn test_multiple_vari32_fields() {
242 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
243 pub struct MultiVarPacket {
244 #[codec(varint32)]
245 pub a: i32,
246 #[codec(varint32)]
247 pub b: i32,
248 #[codec(varint32)]
249 pub c: i32,
250 }
251
252 let packet = MultiVarPacket {
253 a: 1,
254 b: 128,
255 c: -1,
256 };
257
258 let mut buf = Vec::new();
259 packet.encode(&mut buf);
260
261 let mut slice = buf.as_slice();
262 let decoded = MultiVarPacket::decode(&mut slice).unwrap();
263
264 assert_eq!(decoded, packet);
265 }
266
267 #[test]
268 fn test_mixed_vari32_and_regular() {
269 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
270 pub struct MixedPacket {
271 pub regular: u8,
272 #[codec(varint32)]
273 pub compact: i32,
274 pub regular2: i32,
275 #[codec(varint32)]
276 pub compact2: i32,
277 }
278
279 let packet = MixedPacket {
280 regular: 255,
281 compact: 100,
282 regular2: 0x12345678,
283 compact2: 50000,
284 };
285
286 let mut buf = Vec::new();
287 packet.encode(&mut buf);
288
289 let mut slice = buf.as_slice();
290 let decoded = MixedPacket::decode(&mut slice).unwrap();
291
292 assert_eq!(decoded, packet);
293 }
294
295 #[test]
296 fn test_nested_structs() {
297 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
298 pub struct Inner {
299 pub value: u8,
300 }
301
302 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
303 pub struct Outer {
304 pub inner: Inner,
305 pub extra: i32,
306 }
307
308 let packet = Outer {
309 inner: Inner { value: 42 },
310 extra: 12345,
311 };
312
313 let mut buf = Vec::new();
314 packet.encode(&mut buf);
315
316 let mut slice = buf.as_slice();
317 let decoded = Outer::decode(&mut slice).unwrap();
318
319 assert_eq!(decoded, packet);
320 }
321
322 #[test]
323 fn test_large_varint() {
324 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
325 pub struct LargeVarPacket {
326 #[codec(varint32)]
327 pub value: i32,
328 }
329
330 let packet = LargeVarPacket { value: 268435455 };
331
332 let mut buf = Vec::new();
333 packet.encode(&mut buf);
334
335 assert_eq!(buf.len(), 4);
336
337 let mut slice = buf.as_slice();
338 let decoded = LargeVarPacket::decode(&mut slice).unwrap();
339
340 assert_eq!(decoded, packet);
341 }
342
343 #[test]
344 fn test_repr_u8_enum() {
345 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
346 #[repr(u8)]
347 pub enum SimpleEnum {
348 First = 0,
349 Second = 1,
350 Third = 42,
351 }
352
353 for variant in [SimpleEnum::First, SimpleEnum::Second, SimpleEnum::Third] {
354 let mut buf = Vec::new();
355 variant.encode(&mut buf);
356
357 assert_eq!(buf.len(), 1);
358
359 let mut slice = buf.as_slice();
360 let decoded = SimpleEnum::decode(&mut slice).unwrap();
361
362 assert_eq!(decoded, variant);
363 assert_eq!(slice.len(), 0);
364 }
365 }
366
367 #[test]
368 fn test_repr_i32_enum() {
369 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
370 #[repr(i32)]
371 pub enum StatusEnum {
372 Pending = -1,
373 Active = 0,
374 Complete = 1,
375 }
376
377 for variant in [
378 StatusEnum::Pending,
379 StatusEnum::Active,
380 StatusEnum::Complete,
381 ] {
382 let mut buf = Vec::new();
383 variant.encode(&mut buf);
384
385 assert_eq!(buf.len(), 4);
386
387 let mut slice = buf.as_slice();
388 let decoded = StatusEnum::decode(&mut slice).unwrap();
389
390 assert_eq!(decoded, variant);
391 assert_eq!(slice.len(), 0);
392 }
393 }
394
395 #[test]
396 fn test_repr_i32_enum_varint32_compression() {
397 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
398 #[codec(varint32)]
399 #[repr(i32)]
400 pub enum CompressedEnum {
401 Small = 0,
402 Medium = 100,
403 Large = 268435455,
404 }
405
406 let variant = CompressedEnum::Large;
407 let mut buf = Vec::new();
408 variant.encode(&mut buf);
409
410 assert_eq!(buf.len(), 4);
411
412 let mut slice = buf.as_slice();
413 let decoded = CompressedEnum::decode(&mut slice).unwrap();
414
415 assert_eq!(decoded, variant);
416 }
417
418 #[test]
419 fn test_repr_u8_enum_invalid_discriminant() {
420 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
421 #[repr(u8)]
422 pub enum StatusEnum {
423 Active = 1,
424 Inactive = 2,
425 }
426
427 let buf = vec![99u8];
428 match StatusEnum::decode(&mut buf.as_slice()) {
429 Err(DecodeError::InvalidPacketId(None)) => (),
430 other => panic!("Expected InvalidPacketId error, got {:?}", other),
431 }
432 }
433
434 #[test]
435 fn test_repr_i32_enum_varint32() {
436 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
437 #[codec(varint32)]
438 #[repr(i32)]
439 pub enum VarIntEnum {
440 Zero = 0,
441 One = 1,
442 Hundred = 100,
443 }
444
445 let mut buf = Vec::new();
446 VarIntEnum::Hundred.encode(&mut buf);
447
448 assert!(buf.len() < 4);
449
450 let mut slice = buf.as_slice();
451 let decoded = VarIntEnum::decode(&mut slice).unwrap();
452
453 assert_eq!(decoded, VarIntEnum::Hundred);
454 }
455
456 #[test]
457 fn test_fixed_length_vec_literal() {
458 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
459 pub struct FixedLengthLiteral {
460 #[codec(fixed_length = 3)]
461 pub data: Vec<u8>,
462 }
463
464 let original = FixedLengthLiteral {
465 data: vec![1, 2, 3],
466 };
467
468 let mut buf = Vec::new();
469 original.encode(&mut buf);
470
471 let mut slice = buf.as_slice();
472 let decoded = FixedLengthLiteral::decode(&mut slice).unwrap();
473
474 assert_eq!(decoded, original);
475 }
476
477 #[test]
478 fn test_fixed_length_vec_field_reference() {
479 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
480 pub struct FixedLengthFieldRef {
481 pub length: u32,
482 #[codec(fixed_length = length)]
483 pub data: Vec<u8>,
484 }
485
486 let original = FixedLengthFieldRef {
487 length: 5,
488 data: vec![10, 20, 30, 40, 50],
489 };
490
491 let mut buf = Vec::new();
492 original.encode(&mut buf);
493
494 let mut slice = buf.as_slice();
495 let decoded = FixedLengthFieldRef::decode(&mut slice).unwrap();
496
497 assert_eq!(decoded, original);
498 }
499
500 #[test]
501 fn test_fixed_length_vec_arithmetic() {
502 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
503 pub struct FixedLengthArithmetic {
504 pub length: u32,
505 pub factor: u32,
506 #[codec(fixed_length = length * factor)]
507 pub data: Vec<u8>,
508 }
509
510 let original = FixedLengthArithmetic {
511 length: 3,
512 factor: 2,
513 data: vec![1, 2, 3, 4, 5, 6],
514 };
515
516 let mut buf = Vec::new();
517 original.encode(&mut buf);
518
519 let mut slice = buf.as_slice();
520 let decoded = FixedLengthArithmetic::decode(&mut slice).unwrap();
521
522 assert_eq!(decoded, original);
523 }
524
525 #[test]
526 fn test_fixed_length_vec_complex_expression() {
527 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
528 pub struct FixedLengthComplex {
529 pub length: u32,
530 pub factor: u32,
531 #[codec(fixed_length = (length + 5) * factor - 2)]
532 pub data: Vec<u8>,
533 }
534
535 let original = FixedLengthComplex {
537 length: 4,
538 factor: 2,
539 data: vec![1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
540 };
541
542 let mut buf = Vec::new();
543 original.encode(&mut buf);
544
545 let mut slice = buf.as_slice();
546 let decoded = FixedLengthComplex::decode(&mut slice).unwrap();
547
548 assert_eq!(decoded, original);
549 }
550
551 #[test]
552 fn test_fixed_length_vec_multiple_fields() {
553 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
554 pub struct MultipleFixedLength {
555 pub length: u32,
556 pub factor: u32,
557 #[codec(fixed_length = length)]
558 pub field_a: Vec<u8>,
559 #[codec(fixed_length = length * factor)]
560 pub field_b: Vec<u8>,
561 #[codec(fixed_length = 2)]
562 pub field_c: Vec<u8>,
563 }
564
565 let original = MultipleFixedLength {
566 length: 3,
567 factor: 2,
568 field_a: vec![1, 2, 3],
569 field_b: vec![4, 5, 6, 7, 8, 9],
570 field_c: vec![10, 11],
571 };
572
573 let mut buf = Vec::new();
574 original.encode(&mut buf);
575
576 let mut slice = buf.as_slice();
577 let decoded = MultipleFixedLength::decode(&mut slice).unwrap();
578
579 assert_eq!(decoded, original);
580 }
581
582 #[test]
583 #[should_panic(expected = "Fixed-length vector length mismatch")]
584 fn test_fixed_length_vec_wrong_length() {
585 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
586 pub struct FixedLengthWrong {
587 #[codec(fixed_length = 3)]
588 pub data: Vec<u8>,
589 }
590
591 let invalid = FixedLengthWrong {
592 data: vec![1, 2], };
594
595 let mut buf = Vec::new();
596 invalid.encode(&mut buf); }
598
599 #[test]
600 fn test_fixed_length_no_length_prefix() {
601 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
603 pub struct FixedLengthNormal {
604 pub length: u32,
605 #[codec(fixed_length = length)]
606 pub data: Vec<u8>,
607 }
608
609 let original = FixedLengthNormal {
610 length: 5,
611 data: vec![10, 20, 30, 40, 50],
612 };
613
614 let mut buf = Vec::new();
615 original.encode(&mut buf);
616
617 assert_eq!(
622 buf.len(),
623 9,
624 "Fixed-length vector should not include length prefix"
625 );
626 assert_eq!(buf[0..4], [0, 0, 0, 5]); assert_eq!(buf[4..9], [10, 20, 30, 40, 50]); }
629
630 #[test]
631 fn test_fixed_length_vs_normal_vector_size() {
632 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode)]
634 pub struct WithNormalVector {
635 pub data: Vec<u8>,
636 }
637
638 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode)]
639 pub struct WithFixedLengthVector {
640 pub length: u32,
641 #[codec(fixed_length = length)]
642 pub data: Vec<u8>,
643 }
644
645 let data = vec![1, 2, 3, 4, 5];
646
647 let normal = WithNormalVector { data: data.clone() };
648
649 let fixed = WithFixedLengthVector {
650 length: 5,
651 data: data.clone(),
652 };
653
654 let mut normal_buf = Vec::new();
655 normal.encode(&mut normal_buf);
656
657 let mut fixed_buf = Vec::new();
658 fixed.encode(&mut fixed_buf);
659
660 assert_eq!(
664 normal_buf.len(),
665 6,
666 "Normal vector should include 1-byte varint32 length prefix"
667 );
668 assert_eq!(normal_buf[0], 5); assert_eq!(normal_buf[1..], [1, 2, 3, 4, 5]); assert_eq!(
672 fixed_buf.len(),
673 9,
674 "Fixed-length vector struct includes u32 field"
675 );
676 assert_eq!(fixed_buf[0..4], [0, 0, 0, 5]); assert_eq!(fixed_buf[4..9], [1, 2, 3, 4, 5]); }
679
680 #[test]
681 fn test_fixed_length_decode_from_raw_bytes() {
682 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
684 pub struct FixedLengthManual {
685 pub length: u32,
686 #[codec(fixed_length = length)]
687 pub data: Vec<u8>,
688 }
689
690 let buf = vec![0x00, 0x00, 0x00, 0x05, 100, 101, 102, 103, 104];
694
695 let mut slice = buf.as_slice();
696 let decoded = FixedLengthManual::decode(&mut slice).unwrap();
697
698 assert_eq!(decoded.length, 5);
699 assert_eq!(decoded.data, vec![100, 101, 102, 103, 104]);
700 assert_eq!(slice.len(), 0);
702 }
703
704 #[test]
705 fn test_fixed_length_roundtrip_preserves_format() {
706 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
708 pub struct FixedLengthRoundtrip {
709 pub length: u32,
710 #[codec(fixed_length = length)]
711 pub data: Vec<u8>,
712 }
713
714 let original = FixedLengthRoundtrip {
715 length: 3,
716 data: vec![42, 43, 44],
717 };
718
719 let mut buf1 = Vec::new();
721 original.encode(&mut buf1);
722
723 let mut slice = buf1.as_slice();
725 let decoded = FixedLengthRoundtrip::decode(&mut slice).unwrap();
726
727 let mut buf2 = Vec::new();
729 decoded.encode(&mut buf2);
730
731 assert_eq!(
733 buf1, buf2,
734 "Roundtrip encode/decode should produce identical bytes"
735 );
736 }
737
738 #[test]
739 fn test_fixed_length_multiple_fields_binary_format() {
740 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
742 pub struct MultipleFix {
743 pub len_a: u32,
744 pub len_b: u32,
745 #[codec(fixed_length = len_a)]
746 pub field_a: Vec<u8>,
747 #[codec(fixed_length = len_b)]
748 pub field_b: Vec<u8>,
749 }
750
751 let original = MultipleFix {
752 len_a: 2,
753 len_b: 3,
754 field_a: vec![1, 2],
755 field_b: vec![10, 11, 12],
756 };
757
758 let mut buf = Vec::new();
759 original.encode(&mut buf);
760
761 assert_eq!(buf.len(), 13);
768 assert_eq!(buf[0..4], [0, 0, 0, 2]); assert_eq!(buf[4..8], [0, 0, 0, 3]); assert_eq!(buf[8..10], [1, 2]); assert_eq!(buf[10..13], [10, 11, 12]); }
773
774 #[test]
775 fn test_fixed_length_with_expression_binary() {
776 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
778 pub struct FixedWithExpr {
779 pub base: u32,
780 pub multiplier: u32,
781 #[codec(fixed_length = base * multiplier)]
782 pub data: Vec<u8>,
783 }
784
785 let original = FixedWithExpr {
786 base: 3,
787 multiplier: 2,
788 data: vec![1, 2, 3, 4, 5, 6],
789 };
790
791 let mut buf = Vec::new();
792 original.encode(&mut buf);
793
794 assert_eq!(buf.len(), 14);
800
801 let mut slice = buf.as_slice();
803 let decoded = FixedWithExpr::decode(&mut slice).unwrap();
804 assert_eq!(decoded, original);
805 assert_eq!(slice.len(), 0);
806 }
807
808 #[test]
809 fn test_fixed_length_vec_u8_large_buffer() {
810 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
813 pub struct LargeFixedBuffer {
814 pub size: u32,
815 #[codec(fixed_length = size)]
816 pub data: Vec<u8>,
817 }
818
819 let large_data = vec![42u8; 10000];
821 let original = LargeFixedBuffer {
822 size: 10000,
823 data: large_data.clone(),
824 };
825
826 let mut buf = Vec::new();
827 original.encode(&mut buf);
828
829 assert_eq!(buf.len(), 10004);
831
832 let mut slice = buf.as_slice();
834 let decoded = LargeFixedBuffer::decode(&mut slice).unwrap();
835
836 assert_eq!(decoded.size, 10000);
837 assert_eq!(decoded.data, large_data);
838 assert_eq!(slice.len(), 0);
839 }
840
841 #[test]
842 fn test_fixed_length_vec_u8_optimized_vs_generic() {
843 #[derive(voidmc_codec_macros::Encode, voidmc_codec_macros::Decode, PartialEq, Debug)]
845 pub struct MixedVectors {
846 pub len: u32,
847 #[codec(fixed_length = len)]
848 pub bytes: Vec<u8>,
849 #[codec(fixed_length = len)]
850 pub numbers: Vec<u16>,
851 }
852
853 let original = MixedVectors {
854 len: 5,
855 bytes: vec![1, 2, 3, 4, 5],
856 numbers: vec![100, 101, 102, 103, 104],
857 };
858
859 let mut buf = Vec::new();
860 original.encode(&mut buf);
861
862 assert_eq!(buf.len(), 19);
867
868 let mut slice = buf.as_slice();
869 let decoded = MixedVectors::decode(&mut slice).unwrap();
870
871 assert_eq!(decoded, original);
872 assert_eq!(slice.len(), 0);
873 }
874
875 #[derive(Encode, Decode, Debug, PartialEq)]
877 struct SimpleRemaining {
878 id: u32,
879 #[codec(remaining)]
880 data: Vec<u8>,
881 }
882
883 #[test]
884 fn test_remaining_basic() {
885 let original = SimpleRemaining {
886 id: 42,
887 data: vec![1, 2, 3, 4, 5],
888 };
889
890 let mut buf = Vec::new();
891 original.encode(&mut buf);
892
893 assert_eq!(buf.len(), 9);
895
896 let mut slice = buf.as_slice();
897 let decoded = SimpleRemaining::decode(&mut slice).unwrap();
898
899 assert_eq!(decoded, original);
900 assert_eq!(slice.len(), 0); }
902
903 #[test]
904 fn test_remaining_empty() {
905 let original = SimpleRemaining {
906 id: 100,
907 data: vec![],
908 };
909
910 let mut buf = Vec::new();
911 original.encode(&mut buf);
912
913 assert_eq!(buf.len(), 4);
915
916 let mut slice = buf.as_slice();
917 let decoded = SimpleRemaining::decode(&mut slice).unwrap();
918
919 assert_eq!(decoded, original);
920 assert_eq!(slice.len(), 0);
921 }
922
923 #[test]
924 fn test_remaining_large_data() {
925 let data = vec![42u8; 10000];
926 let original = SimpleRemaining {
927 id: 999,
928 data: data.clone(),
929 };
930
931 let mut buf = Vec::new();
932 original.encode(&mut buf);
933
934 assert_eq!(buf.len(), 10004);
936
937 let mut slice = buf.as_slice();
938 let decoded = SimpleRemaining::decode(&mut slice).unwrap();
939
940 assert_eq!(decoded, original);
941 assert_eq!(slice.len(), 0);
942 }
943
944 #[test]
945 fn test_remaining_consumes_all_bytes() {
946 let original = SimpleRemaining {
947 id: 1,
948 data: vec![10, 20, 30],
949 };
950
951 let mut buf = Vec::new();
952 original.encode(&mut buf);
953
954 buf.push(255);
956 buf.push(254);
957 buf.push(253);
958
959 let mut slice = buf.as_slice();
960 let decoded = SimpleRemaining::decode(&mut slice).unwrap();
961
962 assert_eq!(slice.len(), 0);
964
965 assert_eq!(decoded.data, vec![10, 20, 30, 255, 254, 253]);
967 }
968
969 #[test]
970 fn test_remaining_no_length_prefix() {
971 let original = SimpleRemaining {
972 id: 5,
973 data: vec![100, 101, 102],
974 };
975
976 let mut buf = Vec::new();
977 original.encode(&mut buf);
978
979 assert_eq!(buf[0..4], [0, 0, 0, 5]);
984 assert_eq!(buf[4..7], [100, 101, 102]);
985 assert_eq!(buf.len(), 7);
986 }
987
988 #[test]
989 fn test_remaining_with_string_field() {
990 #[derive(Encode, Decode, Debug, PartialEq)]
991 struct MessageWithData {
992 channel: String,
993 #[codec(remaining)]
994 payload: Vec<u8>,
995 }
996
997 let original = MessageWithData {
998 channel: "test_channel".to_string(),
999 payload: vec![1, 2, 3, 4],
1000 };
1001
1002 let mut buf = Vec::new();
1003 original.encode(&mut buf);
1004
1005 let mut slice = buf.as_slice();
1006 let decoded = MessageWithData::decode(&mut slice).unwrap();
1007
1008 assert_eq!(decoded, original);
1009 assert_eq!(slice.len(), 0);
1010 }
1011
1012 #[test]
1013 fn test_remaining_multiple_u8_fields() {
1014 #[derive(Encode, Decode, Debug, PartialEq)]
1015 struct MultiField {
1016 byte1: u8,
1017 byte2: u8,
1018 #[codec(remaining)]
1019 rest: Vec<u8>,
1020 }
1021
1022 let original = MultiField {
1023 byte1: 10,
1024 byte2: 20,
1025 rest: vec![30, 40, 50, 60],
1026 };
1027
1028 let mut buf = Vec::new();
1029 original.encode(&mut buf);
1030
1031 assert_eq!(buf.len(), 6);
1033
1034 let mut slice = buf.as_slice();
1035 let decoded = MultiField::decode(&mut slice).unwrap();
1036
1037 assert_eq!(decoded, original);
1038 assert_eq!(slice.len(), 0);
1039 }
1040
1041 #[test]
1042 fn test_remaining_preserves_all_bytes() {
1043 let data = b"Plugin message with binary \x00\x01\x02\x03 data".to_vec();
1044 let original = SimpleRemaining {
1045 id: 777,
1046 data: data.clone(),
1047 };
1048
1049 let mut buf = Vec::new();
1050 original.encode(&mut buf);
1051
1052 let mut slice = buf.as_slice();
1053 let decoded = SimpleRemaining::decode(&mut slice).unwrap();
1054
1055 assert_eq!(decoded.data, data);
1057 assert_eq!(slice.len(), 0);
1058 }
1059
1060 #[test]
1061 fn test_remaining_roundtrip_multiple_times() {
1062 let test_cases = vec![
1063 vec![],
1064 vec![1],
1065 vec![1, 2, 3, 4, 5],
1066 vec![255, 254, 253],
1067 vec![0; 100],
1068 ];
1069
1070 for data in test_cases {
1071 let original = SimpleRemaining {
1072 id: 42,
1073 data: data.clone(),
1074 };
1075
1076 let mut buf = Vec::new();
1077 original.encode(&mut buf);
1078
1079 let mut slice = buf.as_slice();
1080 let decoded = SimpleRemaining::decode(&mut slice).unwrap();
1081
1082 assert_eq!(decoded, original, "Roundtrip failed for data: {:?}", data);
1083 assert_eq!(slice.len(), 0);
1084
1085 let mut buf2 = Vec::new();
1087 decoded.encode(&mut buf2);
1088 assert_eq!(buf, buf2, "Encode changed for data: {:?}", data);
1089 }
1090 }
1091
1092 #[test]
1093 fn test_remaining_vs_fixed_length_size_difference() {
1094 #[derive(Encode, Decode, Debug, PartialEq)]
1100 struct WithFixedKnownLen {
1101 #[codec(fixed_length = 4)]
1102 data: Vec<u8>,
1103 }
1104
1105 #[derive(Encode, Decode, Debug, PartialEq)]
1106 struct WithRemaining {
1107 #[codec(remaining)]
1108 data: Vec<u8>,
1109 }
1110
1111 let data = vec![1, 2, 3, 4];
1112
1113 let fixed = WithFixedKnownLen { data: data.clone() };
1114
1115 let remaining = WithRemaining { data: data.clone() };
1116
1117 let mut buf_fixed = Vec::new();
1118 fixed.encode(&mut buf_fixed);
1119
1120 let mut buf_remaining = Vec::new();
1121 remaining.encode(&mut buf_remaining);
1122
1123 assert_eq!(buf_fixed.len(), buf_remaining.len());
1126 assert_eq!(buf_fixed, buf_remaining);
1127 }
1128}