1use super::error::BinaryError;
7use super::frame::BinaryFrame;
8use crate::encoder::Encoder;
9use lnmp_core::LnmpRecord;
10
11#[derive(Debug, Clone)]
13pub struct DecoderConfig {
14 pub validate_ordering: bool,
16 pub strict_parsing: bool,
18
19 pub allow_streaming: bool,
22 pub validate_nesting: bool,
24 pub allow_delta: bool,
26 pub max_depth: usize,
28}
29
30impl Default for DecoderConfig {
31 fn default() -> Self {
32 Self {
33 validate_ordering: false,
34 strict_parsing: false,
35 allow_streaming: false,
37 validate_nesting: false,
38 allow_delta: false,
39 max_depth: 32,
40 }
41 }
42}
43
44impl DecoderConfig {
45 pub fn new() -> Self {
47 Self::default()
48 }
49
50 pub fn with_validate_ordering(mut self, validate: bool) -> Self {
52 self.validate_ordering = validate;
53 self
54 }
55
56 pub fn with_strict_parsing(mut self, strict: bool) -> Self {
58 self.strict_parsing = strict;
59 self
60 }
61
62 pub fn with_streaming(mut self, allow: bool) -> Self {
66 self.allow_streaming = allow;
67 self
68 }
69
70 pub fn with_validate_nesting(mut self, validate: bool) -> Self {
72 self.validate_nesting = validate;
73 self
74 }
75
76 pub fn with_delta(mut self, allow: bool) -> Self {
78 self.allow_delta = allow;
79 self
80 }
81
82 pub fn with_max_depth(mut self, depth: usize) -> Self {
84 self.max_depth = depth;
85 self
86 }
87}
88
89#[derive(Debug)]
116pub struct BinaryDecoder {
117 config: DecoderConfig,
118}
119
120impl BinaryDecoder {
121 pub fn new() -> Self {
127 Self {
128 config: DecoderConfig::default(),
129 }
130 }
131
132 pub fn with_config(config: DecoderConfig) -> Self {
134 Self { config }
135 }
136
137 pub fn decode(&self, bytes: &[u8]) -> Result<LnmpRecord, BinaryError> {
162 let frame = if self.config.validate_ordering {
164 BinaryFrame::decode(bytes)?
165 } else {
166 BinaryFrame::decode_allow_unsorted(bytes)?
167 };
168
169 let record = frame.to_record();
171
172 if self.config.validate_ordering {
174 self.validate_field_ordering(&record)?;
175 }
176
177 if self.config.strict_parsing {
179 let consumed = self.calculate_frame_size(bytes)?;
181 if consumed < bytes.len() {
182 return Err(BinaryError::TrailingData {
183 bytes_remaining: bytes.len() - consumed,
184 });
185 }
186 }
187
188 Ok(record)
189 }
190
191 pub fn decode_to_text(&self, bytes: &[u8]) -> Result<String, BinaryError> {
222 let record = self.decode(bytes)?;
224
225 let encoder = Encoder::new();
227 Ok(encoder.encode(&record))
228 }
229
230 fn validate_field_ordering(&self, record: &LnmpRecord) -> Result<(), BinaryError> {
232 let fields = record.fields();
233
234 for i in 1..fields.len() {
235 if fields[i].fid < fields[i - 1].fid {
236 return Err(BinaryError::CanonicalViolation {
237 reason: format!(
238 "Fields not in ascending FID order: F{} appears after F{}",
239 fields[i].fid,
240 fields[i - 1].fid
241 ),
242 });
243 }
244 }
245
246 Ok(())
247 }
248
249 fn calculate_frame_size(&self, bytes: &[u8]) -> Result<usize, BinaryError> {
251 let mut offset = 0;
254
255 if bytes.is_empty() {
257 return Err(BinaryError::UnexpectedEof {
258 expected: 1,
259 found: bytes.len(),
260 });
261 }
262 offset += 1;
263
264 if bytes.len() < offset + 1 {
266 return Err(BinaryError::UnexpectedEof {
267 expected: offset + 1,
268 found: bytes.len(),
269 });
270 }
271 offset += 1;
272
273 let (entry_count, consumed) =
275 super::varint::decode(&bytes[offset..]).map_err(|_| BinaryError::InvalidVarInt {
276 reason: "Invalid entry count VarInt".to_string(),
277 })?;
278 offset += consumed;
279
280 if entry_count < 0 {
281 return Err(BinaryError::InvalidValue {
282 field_id: 0,
283 type_tag: 0,
284 reason: format!("Negative entry count: {}", entry_count),
285 });
286 }
287
288 let entry_count = entry_count as usize;
289
290 for _ in 0..entry_count {
292 let (_, consumed) = super::entry::BinaryEntry::decode(&bytes[offset..])?;
293 offset += consumed;
294 }
295
296 Ok(offset)
297 }
298
299 pub fn detect_version(&self, bytes: &[u8]) -> Result<u8, BinaryError> {
328 if bytes.is_empty() {
329 return Err(BinaryError::UnexpectedEof {
330 expected: 1,
331 found: 0,
332 });
333 }
334 Ok(bytes[0])
335 }
336
337 pub fn supports_nested(&self, bytes: &[u8]) -> bool {
361 if bytes.len() < 3 {
365 return false; }
367
368 let mut offset = 0;
369
370 offset += 1;
372
373 offset += 1;
375
376 let (entry_count, consumed) = match super::varint::decode(&bytes[offset..]) {
378 Ok(result) => result,
379 Err(_) => return false,
380 };
381 offset += consumed;
382
383 if entry_count < 0 {
384 return false;
385 }
386
387 let entry_count = entry_count as usize;
388
389 for _ in 0..entry_count {
391 if offset >= bytes.len() {
392 return false;
393 }
394
395 match super::entry::BinaryEntry::decode(&bytes[offset..]) {
397 Ok((entry, consumed)) => {
398 let type_tag = entry.type_tag();
400 if type_tag.is_v0_5_type() {
401 return true;
402 }
403 offset += consumed;
404 }
405 Err(_) => return false,
406 }
407 }
408
409 false
410 }
411}
412
413impl Default for BinaryDecoder {
414 fn default() -> Self {
415 Self::new()
416 }
417}
418
419#[cfg(test)]
420mod tests {
421 #![allow(clippy::approx_constant)]
422
423 use super::super::encoder::BinaryEncoder;
424 use super::*;
425 use lnmp_core::{LnmpField, LnmpValue};
426
427 #[test]
428 fn test_new_decoder() {
429 let decoder = BinaryDecoder::new();
430 assert!(!decoder.config.validate_ordering);
431 assert!(!decoder.config.strict_parsing);
432 assert!(!decoder.config.allow_streaming);
434 assert!(!decoder.config.validate_nesting);
435 assert!(!decoder.config.allow_delta);
436 assert_eq!(decoder.config.max_depth, 32);
437 }
438
439 #[test]
440 fn test_decoder_with_config() {
441 let config = DecoderConfig::new()
442 .with_validate_ordering(true)
443 .with_strict_parsing(true);
444
445 let decoder = BinaryDecoder::with_config(config);
446 assert!(decoder.config.validate_ordering);
447 assert!(decoder.config.strict_parsing);
448 }
449
450 #[test]
451 fn test_decode_empty_record() {
452 let encoder = BinaryEncoder::new();
453 let record = LnmpRecord::new();
454 let binary = encoder.encode(&record).unwrap();
455
456 let decoder = BinaryDecoder::new();
457 let decoded = decoder.decode(&binary).unwrap();
458
459 assert_eq!(decoded.fields().len(), 0);
460 }
461
462 #[test]
463 fn test_decode_single_field() {
464 let mut record = LnmpRecord::new();
465 record.add_field(LnmpField {
466 fid: 7,
467 value: LnmpValue::Bool(true),
468 });
469
470 let encoder = BinaryEncoder::new();
471 let binary = encoder.encode(&record).unwrap();
472
473 let decoder = BinaryDecoder::new();
474 let decoded = decoder.decode(&binary).unwrap();
475
476 assert_eq!(decoded.fields().len(), 1);
477 assert_eq!(decoded.get_field(7).unwrap().value, LnmpValue::Bool(true));
478 }
479
480 #[test]
481 fn test_decode_multiple_fields() {
482 let mut record = LnmpRecord::new();
483 record.add_field(LnmpField {
484 fid: 7,
485 value: LnmpValue::Bool(true),
486 });
487 record.add_field(LnmpField {
488 fid: 12,
489 value: LnmpValue::Int(14532),
490 });
491 record.add_field(LnmpField {
492 fid: 23,
493 value: LnmpValue::StringArray(vec!["admin".to_string(), "dev".to_string()]),
494 });
495
496 let encoder = BinaryEncoder::new();
497 let binary = encoder.encode(&record).unwrap();
498
499 let decoder = BinaryDecoder::new();
500 let decoded = decoder.decode(&binary).unwrap();
501
502 assert_eq!(decoded.fields().len(), 3);
503 assert_eq!(decoded.get_field(7).unwrap().value, LnmpValue::Bool(true));
504 assert_eq!(decoded.get_field(12).unwrap().value, LnmpValue::Int(14532));
505 assert_eq!(
506 decoded.get_field(23).unwrap().value,
507 LnmpValue::StringArray(vec!["admin".to_string(), "dev".to_string()])
508 );
509 }
510
511 #[test]
512 fn test_decode_all_types() {
513 let mut record = LnmpRecord::new();
514 record.add_field(LnmpField {
515 fid: 1,
516 value: LnmpValue::Int(-42),
517 });
518 record.add_field(LnmpField {
519 fid: 2,
520 value: LnmpValue::Float(3.14159),
521 });
522 record.add_field(LnmpField {
523 fid: 3,
524 value: LnmpValue::Bool(false),
525 });
526 record.add_field(LnmpField {
527 fid: 4,
528 value: LnmpValue::String("hello".to_string()),
529 });
530 record.add_field(LnmpField {
531 fid: 5,
532 value: LnmpValue::StringArray(vec!["a".to_string(), "b".to_string()]),
533 });
534
535 let encoder = BinaryEncoder::new();
536 let binary = encoder.encode(&record).unwrap();
537
538 let decoder = BinaryDecoder::new();
539 let decoded = decoder.decode(&binary).unwrap();
540
541 assert_eq!(decoded.get_field(1).unwrap().value, LnmpValue::Int(-42));
542 assert_eq!(
543 decoded.get_field(2).unwrap().value,
544 LnmpValue::Float(3.14159)
545 );
546 assert_eq!(decoded.get_field(3).unwrap().value, LnmpValue::Bool(false));
547 assert_eq!(
548 decoded.get_field(4).unwrap().value,
549 LnmpValue::String("hello".to_string())
550 );
551 assert_eq!(
552 decoded.get_field(5).unwrap().value,
553 LnmpValue::StringArray(vec!["a".to_string(), "b".to_string()])
554 );
555 }
556
557 #[test]
558 fn test_decode_unsupported_version() {
559 let bytes = vec![0x99, 0x00, 0x00]; let decoder = BinaryDecoder::new();
561 let result = decoder.decode(&bytes);
562
563 assert!(matches!(
564 result,
565 Err(BinaryError::UnsupportedVersion { found: 0x99, .. })
566 ));
567 }
568
569 #[test]
570 fn test_decode_version_0x04_accepted() {
571 let bytes = vec![0x04, 0x00, 0x00]; let decoder = BinaryDecoder::new();
573 let result = decoder.decode(&bytes);
574
575 assert!(result.is_ok());
576 }
577
578 #[test]
579 fn test_decode_to_text_simple() {
580 let mut record = LnmpRecord::new();
581 record.add_field(LnmpField {
582 fid: 7,
583 value: LnmpValue::Bool(true),
584 });
585
586 let encoder = BinaryEncoder::new();
587 let binary = encoder.encode(&record).unwrap();
588
589 let decoder = BinaryDecoder::new();
590 let text = decoder.decode_to_text(&binary).unwrap();
591
592 assert_eq!(text, "F7=1");
593 }
594
595 #[test]
596 fn test_decode_to_text_multiple_fields() {
597 let mut record = LnmpRecord::new();
598 record.add_field(LnmpField {
599 fid: 7,
600 value: LnmpValue::Bool(true),
601 });
602 record.add_field(LnmpField {
603 fid: 12,
604 value: LnmpValue::Int(14532),
605 });
606 record.add_field(LnmpField {
607 fid: 23,
608 value: LnmpValue::StringArray(vec!["admin".to_string(), "dev".to_string()]),
609 });
610
611 let encoder = BinaryEncoder::new();
612 let binary = encoder.encode(&record).unwrap();
613
614 let decoder = BinaryDecoder::new();
615 let text = decoder.decode_to_text(&binary).unwrap();
616
617 assert_eq!(text, "F7=1\nF12=14532\nF23=[admin,dev]");
619 }
620
621 #[test]
622 fn test_decode_to_text_canonical_format() {
623 let mut record = LnmpRecord::new();
625 record.add_field(LnmpField {
626 fid: 23,
627 value: LnmpValue::StringArray(vec!["admin".to_string()]),
628 });
629 record.add_field(LnmpField {
630 fid: 7,
631 value: LnmpValue::Bool(true),
632 });
633 record.add_field(LnmpField {
634 fid: 12,
635 value: LnmpValue::Int(14532),
636 });
637
638 let encoder = BinaryEncoder::new();
639 let binary = encoder.encode(&record).unwrap();
640
641 let decoder = BinaryDecoder::new();
642 let text = decoder.decode_to_text(&binary).unwrap();
643
644 assert_eq!(text, "F7=1\nF12=14532\nF23=[admin]");
646 }
647
648 #[test]
649 fn test_validate_ordering_accepts_sorted() {
650 let mut record = LnmpRecord::new();
651 record.add_field(LnmpField {
652 fid: 7,
653 value: LnmpValue::Bool(true),
654 });
655 record.add_field(LnmpField {
656 fid: 12,
657 value: LnmpValue::Int(14532),
658 });
659
660 let encoder = BinaryEncoder::new();
661 let binary = encoder.encode(&record).unwrap();
662
663 let config = DecoderConfig::new().with_validate_ordering(true);
664 let decoder = BinaryDecoder::with_config(config);
665 let result = decoder.decode(&binary);
666
667 assert!(result.is_ok());
668 }
669
670 #[test]
671 fn test_trailing_data_detection() {
672 let mut record = LnmpRecord::new();
673 record.add_field(LnmpField {
674 fid: 7,
675 value: LnmpValue::Bool(true),
676 });
677
678 let encoder = BinaryEncoder::new();
679 let mut binary = encoder.encode(&record).unwrap();
680
681 binary.extend_from_slice(&[0xDE, 0xAD, 0xBE, 0xEF]);
683
684 let config = DecoderConfig::new().with_strict_parsing(true);
685 let decoder = BinaryDecoder::with_config(config);
686 let result = decoder.decode(&binary);
687
688 assert!(matches!(
689 result,
690 Err(BinaryError::TrailingData { bytes_remaining: 4 })
691 ));
692 }
693
694 #[test]
695 fn test_trailing_data_ignored_without_strict() {
696 let mut record = LnmpRecord::new();
697 record.add_field(LnmpField {
698 fid: 7,
699 value: LnmpValue::Bool(true),
700 });
701
702 let encoder = BinaryEncoder::new();
703 let mut binary = encoder.encode(&record).unwrap();
704
705 binary.extend_from_slice(&[0xDE, 0xAD, 0xBE, 0xEF]);
707
708 let decoder = BinaryDecoder::new(); let result = decoder.decode(&binary);
710
711 assert!(result.is_ok());
713 }
714
715 #[test]
716 fn test_roundtrip_binary_to_text_to_binary() {
717 let original_text = "F7=1\nF12=14532\nF23=[admin,dev]";
718
719 let encoder = BinaryEncoder::new();
721 let binary1 = encoder.encode_text(original_text).unwrap();
722
723 let decoder = BinaryDecoder::new();
725 let text = decoder.decode_to_text(&binary1).unwrap();
726
727 let binary2 = encoder.encode_text(&text).unwrap();
729
730 assert_eq!(binary1, binary2);
732 }
733
734 #[test]
735 fn test_roundtrip_text_to_binary_to_text() {
736 let original_text = "F7=1\nF12=14532\nF23=[admin,dev]";
737
738 let encoder = BinaryEncoder::new();
740 let binary = encoder.encode_text(original_text).unwrap();
741
742 let decoder = BinaryDecoder::new();
744 let decoded_text = decoder.decode_to_text(&binary).unwrap();
745
746 assert_eq!(decoded_text, original_text);
748 }
749
750 #[test]
751 fn test_roundtrip_unsorted_text() {
752 let unsorted_text = "F23=[admin]\nF7=1\nF12=14532";
753
754 let encoder = BinaryEncoder::new();
756 let binary = encoder.encode_text(unsorted_text).unwrap();
757
758 let decoder = BinaryDecoder::new();
760 let decoded_text = decoder.decode_to_text(&binary).unwrap();
761
762 assert_eq!(decoded_text, "F7=1\nF12=14532\nF23=[admin]");
764 }
765
766 #[test]
767 fn test_roundtrip_all_types() {
768 let test_cases = vec![
769 ("F1=-42", "F1=-42"),
770 ("F2=3.14159", "F2=3.14159"),
771 ("F3=0", "F3=0"),
772 ("F4=1", "F4=1"),
773 ("F5=\"hello\\nworld\"", "F5=\"hello\\nworld\""),
774 ("F6=[\"a\",\"b\",\"c\"]", "F6=[a,b,c]"), ("F7=[]", ""), ];
777
778 for (input, expected) in test_cases {
779 let encoder = BinaryEncoder::new();
780 let binary = encoder.encode_text(input).unwrap();
781
782 let decoder = BinaryDecoder::new();
783 let decoded = decoder.decode_to_text(&binary).unwrap();
784
785 assert_eq!(decoded, expected, "Failed for: {}", input);
786 }
787 }
788
789 #[test]
790 fn test_roundtrip_stability() {
791 let text = "F7=1\nF12=14532";
792
793 let encoder = BinaryEncoder::new();
794 let decoder = BinaryDecoder::new();
795
796 let mut current = text.to_string();
798 for _ in 0..5 {
799 let binary = encoder.encode_text(¤t).unwrap();
800 current = decoder.decode_to_text(&binary).unwrap();
801 }
802
803 assert_eq!(current, text);
804 }
805
806 #[test]
807 fn test_decode_insufficient_data() {
808 let bytes = vec![0x04]; let decoder = BinaryDecoder::new();
810 let result = decoder.decode(&bytes);
811
812 assert!(matches!(result, Err(BinaryError::UnexpectedEof { .. })));
813 }
814
815 #[test]
816 fn test_decode_invalid_entry_count() {
817 let bytes = vec![0x04, 0x00, 0x80]; let decoder = BinaryDecoder::new();
819 let result = decoder.decode(&bytes);
820
821 assert!(matches!(result, Err(BinaryError::InvalidVarInt { .. })));
822 }
823
824 #[test]
825 fn test_decode_empty_string() {
826 let mut record = LnmpRecord::new();
827 record.add_field(LnmpField {
828 fid: 1,
829 value: LnmpValue::String("".to_string()),
830 });
831
832 let encoder = BinaryEncoder::new();
833 let binary = encoder.encode(&record).unwrap();
834
835 let decoder = BinaryDecoder::new();
836 let decoded = decoder.decode(&binary).unwrap();
837
838 assert_eq!(
839 decoded.get_field(1).unwrap().value,
840 LnmpValue::String("".to_string())
841 );
842 }
843
844 #[test]
845 fn test_decode_empty_array() {
846 let mut record = LnmpRecord::new();
847 record.add_field(LnmpField {
848 fid: 1,
849 value: LnmpValue::StringArray(vec![]),
850 });
851
852 let encoder = BinaryEncoder::new();
853 let binary = encoder.encode(&record).unwrap();
854
855 let decoder = BinaryDecoder::new();
856 let decoded = decoder.decode(&binary).unwrap();
857
858 assert_eq!(
859 decoded.get_field(1).unwrap().value,
860 LnmpValue::StringArray(vec![])
861 );
862 }
863
864 #[test]
865 fn test_decode_special_characters() {
866 let mut record = LnmpRecord::new();
867 record.add_field(LnmpField {
868 fid: 1,
869 value: LnmpValue::String("hello\nworld".to_string()),
870 });
871 record.add_field(LnmpField {
872 fid: 2,
873 value: LnmpValue::String("path\\to\\file".to_string()),
874 });
875 record.add_field(LnmpField {
876 fid: 3,
877 value: LnmpValue::String("say \"hello\"".to_string()),
878 });
879
880 let encoder = BinaryEncoder::new();
881 let binary = encoder.encode(&record).unwrap();
882
883 let decoder = BinaryDecoder::new();
884 let decoded = decoder.decode(&binary).unwrap();
885
886 assert_eq!(
887 decoded.get_field(1).unwrap().value,
888 LnmpValue::String("hello\nworld".to_string())
889 );
890 assert_eq!(
891 decoded.get_field(2).unwrap().value,
892 LnmpValue::String("path\\to\\file".to_string())
893 );
894 assert_eq!(
895 decoded.get_field(3).unwrap().value,
896 LnmpValue::String("say \"hello\"".to_string())
897 );
898 }
899
900 #[test]
901 fn test_decode_unicode() {
902 let mut record = LnmpRecord::new();
903 record.add_field(LnmpField {
904 fid: 1,
905 value: LnmpValue::String("emoji: 🎯".to_string()),
906 });
907
908 let encoder = BinaryEncoder::new();
909 let binary = encoder.encode(&record).unwrap();
910
911 let decoder = BinaryDecoder::new();
912 let decoded = decoder.decode(&binary).unwrap();
913
914 assert_eq!(
915 decoded.get_field(1).unwrap().value,
916 LnmpValue::String("emoji: 🎯".to_string())
917 );
918 }
919
920 #[test]
921 fn test_default_decoder() {
922 let decoder = BinaryDecoder::default();
923 assert!(!decoder.config.validate_ordering);
924 assert!(!decoder.config.strict_parsing);
925 }
926
927 #[test]
928 fn test_decoder_config_builder() {
929 let config = DecoderConfig::new()
930 .with_validate_ordering(true)
931 .with_strict_parsing(true);
932
933 assert!(config.validate_ordering);
934 assert!(config.strict_parsing);
935 }
936
937 #[test]
938 fn test_decoder_config_v05_fields() {
939 let config = DecoderConfig::new()
940 .with_streaming(true)
941 .with_validate_nesting(true)
942 .with_delta(true)
943 .with_max_depth(64);
944
945 assert!(config.allow_streaming);
946 assert!(config.validate_nesting);
947 assert!(config.allow_delta);
948 assert_eq!(config.max_depth, 64);
949 }
950
951 #[test]
952 fn test_decoder_config_v05_defaults() {
953 let config = DecoderConfig::default();
954
955 assert!(!config.allow_streaming);
956 assert!(!config.validate_nesting);
957 assert!(!config.allow_delta);
958 assert_eq!(config.max_depth, 32);
959 }
960
961 #[test]
962 fn test_decoder_config_backward_compatibility() {
963 let v04_config = DecoderConfig::new()
965 .with_validate_ordering(true)
966 .with_strict_parsing(true);
967
968 assert!(v04_config.validate_ordering);
970 assert!(v04_config.strict_parsing);
971
972 assert!(!v04_config.allow_streaming);
974 assert!(!v04_config.validate_nesting);
975 assert!(!v04_config.allow_delta);
976 }
977
978 #[test]
979 fn test_decoder_config_mixed_v04_v05() {
980 let config = DecoderConfig::new()
982 .with_validate_ordering(true) .with_streaming(true) .with_strict_parsing(true) .with_delta(true); assert!(config.validate_ordering);
988 assert!(config.strict_parsing);
989 assert!(config.allow_streaming);
990 assert!(config.allow_delta);
991 }
992
993 #[test]
994 fn test_decoder_v04_mode_decoding() {
995 let config = DecoderConfig::new()
997 .with_streaming(false)
998 .with_validate_nesting(false)
999 .with_delta(false);
1000
1001 let decoder = BinaryDecoder::with_config(config);
1002
1003 let mut record = LnmpRecord::new();
1005 record.add_field(LnmpField {
1006 fid: 7,
1007 value: LnmpValue::Bool(true),
1008 });
1009
1010 let encoder = BinaryEncoder::new();
1011 let binary = encoder.encode(&record).unwrap();
1012
1013 let decoded = decoder.decode(&binary).unwrap();
1014
1015 assert_eq!(decoded.fields().len(), 1);
1017 assert_eq!(decoded.get_field(7).unwrap().value, LnmpValue::Bool(true));
1018 }
1019
1020 #[test]
1021 fn test_decoder_v04_compatibility_with_existing_binary() {
1022 let v05_decoder = BinaryDecoder::new(); let mut record = LnmpRecord::new();
1027 record.add_field(LnmpField {
1028 fid: 7,
1029 value: LnmpValue::Bool(true),
1030 });
1031 record.add_field(LnmpField {
1032 fid: 12,
1033 value: LnmpValue::Int(14532),
1034 });
1035
1036 let encoder = BinaryEncoder::new();
1037 let v04_binary = encoder.encode(&record).unwrap();
1038
1039 let decoded = v05_decoder.decode(&v04_binary).unwrap();
1041
1042 assert_eq!(decoded.fields().len(), 2);
1043 assert_eq!(decoded.get_field(7).unwrap().value, LnmpValue::Bool(true));
1044 assert_eq!(decoded.get_field(12).unwrap().value, LnmpValue::Int(14532));
1045 }
1046
1047 #[test]
1048 fn test_decode_large_fid() {
1049 let mut record = LnmpRecord::new();
1050 record.add_field(LnmpField {
1051 fid: 65535,
1052 value: LnmpValue::Int(42),
1053 });
1054
1055 let encoder = BinaryEncoder::new();
1056 let binary = encoder.encode(&record).unwrap();
1057
1058 let decoder = BinaryDecoder::new();
1059 let decoded = decoder.decode(&binary).unwrap();
1060
1061 assert_eq!(decoded.get_field(65535).unwrap().value, LnmpValue::Int(42));
1062 }
1063
1064 #[test]
1065 fn test_decode_large_integer() {
1066 let mut record = LnmpRecord::new();
1067 record.add_field(LnmpField {
1068 fid: 1,
1069 value: LnmpValue::Int(i64::MAX),
1070 });
1071
1072 let encoder = BinaryEncoder::new();
1073 let binary = encoder.encode(&record).unwrap();
1074
1075 let decoder = BinaryDecoder::new();
1076 let decoded = decoder.decode(&binary).unwrap();
1077
1078 assert_eq!(
1079 decoded.get_field(1).unwrap().value,
1080 LnmpValue::Int(i64::MAX)
1081 );
1082 }
1083
1084 #[test]
1085 fn test_decode_negative_integer() {
1086 let mut record = LnmpRecord::new();
1087 record.add_field(LnmpField {
1088 fid: 1,
1089 value: LnmpValue::Int(i64::MIN),
1090 });
1091
1092 let encoder = BinaryEncoder::new();
1093 let binary = encoder.encode(&record).unwrap();
1094
1095 let decoder = BinaryDecoder::new();
1096 let decoded = decoder.decode(&binary).unwrap();
1097
1098 assert_eq!(
1099 decoded.get_field(1).unwrap().value,
1100 LnmpValue::Int(i64::MIN)
1101 );
1102 }
1103}