1use super::error::BinaryError;
9use super::types::{BinaryValue, TypeTag};
10use super::varint;
11use lnmp_core::{FieldId, LnmpField};
12
13#[derive(Debug, Clone, PartialEq)]
15pub struct BinaryEntry {
16 pub fid: FieldId,
18 pub tag: TypeTag,
20 pub value: BinaryValue,
22}
23
24impl BinaryEntry {
25 pub fn new(fid: FieldId, value: BinaryValue) -> Self {
27 Self {
28 fid,
29 tag: value.type_tag(),
30 value,
31 }
32 }
33
34 pub fn from_field(field: &LnmpField) -> Result<Self, BinaryError> {
41 let value = BinaryValue::from_lnmp_value(&field.value).map_err(|e| match e {
42 BinaryError::InvalidValue {
43 type_tag, reason, ..
44 } => BinaryError::InvalidValue {
45 field_id: field.fid,
46 type_tag,
47 reason,
48 },
49 other => other,
50 })?;
51
52 Ok(Self {
53 fid: field.fid,
54 tag: value.type_tag(),
55 value,
56 })
57 }
58
59 pub fn to_field(&self) -> LnmpField {
61 LnmpField {
62 fid: self.fid,
63 value: self.value.to_lnmp_value(),
64 }
65 }
66
67 pub fn type_tag(&self) -> TypeTag {
69 self.tag
70 }
71
72 pub fn encode(&self) -> Vec<u8> {
82 let mut bytes = Vec::new();
83
84 bytes.extend_from_slice(&self.fid.to_le_bytes());
86
87 bytes.push(self.tag.to_u8());
89
90 match &self.value {
92 BinaryValue::Int(i) => {
93 bytes.extend_from_slice(&varint::encode(*i));
95 }
96 BinaryValue::Float(f) => {
97 bytes.extend_from_slice(&f.to_le_bytes());
99 }
100 BinaryValue::Bool(b) => {
101 bytes.push(if *b { 0x01 } else { 0x00 });
103 }
104 BinaryValue::String(s) => {
105 let utf8_bytes = s.as_bytes();
107 bytes.extend_from_slice(&varint::encode(utf8_bytes.len() as i64));
108 bytes.extend_from_slice(utf8_bytes);
109 }
110 BinaryValue::StringArray(arr) => {
111 bytes.extend_from_slice(&varint::encode(arr.len() as i64));
113 for s in arr {
114 let utf8_bytes = s.as_bytes();
115 bytes.extend_from_slice(&varint::encode(utf8_bytes.len() as i64));
116 bytes.extend_from_slice(utf8_bytes);
117 }
118 }
119 BinaryValue::NestedRecord(_) | BinaryValue::NestedArray(_) => {
120 panic!("Nested structure encoding not yet implemented - use BinaryNestedEncoder");
124 }
125 }
126
127 bytes
128 }
129
130 pub fn decode(bytes: &[u8]) -> Result<(Self, usize), BinaryError> {
143 let mut offset = 0;
144
145 if bytes.len() < 2 {
147 return Err(BinaryError::UnexpectedEof {
148 expected: 2,
149 found: bytes.len(),
150 });
151 }
152 let fid = u16::from_le_bytes([bytes[0], bytes[1]]);
153 offset += 2;
154
155 if bytes.len() < offset + 1 {
157 return Err(BinaryError::UnexpectedEof {
158 expected: offset + 1,
159 found: bytes.len(),
160 });
161 }
162 let tag = TypeTag::from_u8(bytes[offset])?;
163 offset += 1;
164
165 let value = match tag {
167 TypeTag::NestedRecord | TypeTag::NestedArray => {
168 return Err(BinaryError::InvalidValue {
170 field_id: fid,
171 type_tag: tag.to_u8(),
172 reason:
173 "Nested structure decoding not yet implemented - use BinaryNestedDecoder"
174 .to_string(),
175 });
176 }
177 TypeTag::Reserved08
178 | TypeTag::Reserved09
179 | TypeTag::Reserved0A
180 | TypeTag::Reserved0B
181 | TypeTag::Reserved0C
182 | TypeTag::Reserved0D
183 | TypeTag::Reserved0E
184 | TypeTag::Reserved0F => {
185 return Err(BinaryError::InvalidValue {
186 field_id: fid,
187 type_tag: tag.to_u8(),
188 reason: format!("Reserved type tag 0x{:02X} cannot be used", tag.to_u8()),
189 });
190 }
191 TypeTag::Int => {
192 let (int_val, consumed) =
193 varint::decode(&bytes[offset..]).map_err(|_| BinaryError::InvalidValue {
194 field_id: fid,
195 type_tag: tag.to_u8(),
196 reason: "Invalid VarInt encoding".to_string(),
197 })?;
198 offset += consumed;
199 BinaryValue::Int(int_val)
200 }
201 TypeTag::Float => {
202 if bytes.len() < offset + 8 {
203 return Err(BinaryError::UnexpectedEof {
204 expected: offset + 8,
205 found: bytes.len(),
206 });
207 }
208 let float_bytes: [u8; 8] = bytes[offset..offset + 8]
209 .try_into()
210 .expect("slice length checked");
211 let float_val = f64::from_le_bytes(float_bytes);
212 offset += 8;
213 BinaryValue::Float(float_val)
214 }
215 TypeTag::Bool => {
216 if bytes.len() < offset + 1 {
217 return Err(BinaryError::UnexpectedEof {
218 expected: offset + 1,
219 found: bytes.len(),
220 });
221 }
222 let bool_val = match bytes[offset] {
223 0x00 => false,
224 0x01 => true,
225 other => {
226 return Err(BinaryError::InvalidValue {
227 field_id: fid,
228 type_tag: tag.to_u8(),
229 reason: format!(
230 "Invalid boolean value: 0x{:02X} (expected 0x00 or 0x01)",
231 other
232 ),
233 });
234 }
235 };
236 offset += 1;
237 BinaryValue::Bool(bool_val)
238 }
239 TypeTag::String => {
240 let (length, consumed) =
241 varint::decode(&bytes[offset..]).map_err(|_| BinaryError::InvalidValue {
242 field_id: fid,
243 type_tag: tag.to_u8(),
244 reason: "Invalid string length VarInt".to_string(),
245 })?;
246 offset += consumed;
247
248 if length < 0 {
249 return Err(BinaryError::InvalidValue {
250 field_id: fid,
251 type_tag: tag.to_u8(),
252 reason: format!("Negative string length: {}", length),
253 });
254 }
255
256 let length = length as usize;
257 if bytes.len() < offset + length {
258 return Err(BinaryError::UnexpectedEof {
259 expected: offset + length,
260 found: bytes.len(),
261 });
262 }
263
264 let string_val = std::str::from_utf8(&bytes[offset..offset + length])
265 .map_err(|_| BinaryError::InvalidUtf8 { field_id: fid })?
266 .to_string();
267 offset += length;
268 BinaryValue::String(string_val)
269 }
270 TypeTag::StringArray => {
271 let (count, consumed) =
272 varint::decode(&bytes[offset..]).map_err(|_| BinaryError::InvalidValue {
273 field_id: fid,
274 type_tag: tag.to_u8(),
275 reason: "Invalid array count VarInt".to_string(),
276 })?;
277 offset += consumed;
278
279 if count < 0 {
280 return Err(BinaryError::InvalidValue {
281 field_id: fid,
282 type_tag: tag.to_u8(),
283 reason: format!("Negative array count: {}", count),
284 });
285 }
286
287 let count = count as usize;
288 let mut strings = Vec::with_capacity(count);
289
290 for _ in 0..count {
291 let (length, consumed) = varint::decode(&bytes[offset..]).map_err(|_| {
292 BinaryError::InvalidValue {
293 field_id: fid,
294 type_tag: tag.to_u8(),
295 reason: "Invalid string length in array".to_string(),
296 }
297 })?;
298 offset += consumed;
299
300 if length < 0 {
301 return Err(BinaryError::InvalidValue {
302 field_id: fid,
303 type_tag: tag.to_u8(),
304 reason: format!("Negative string length in array: {}", length),
305 });
306 }
307
308 let length = length as usize;
309 if bytes.len() < offset + length {
310 return Err(BinaryError::UnexpectedEof {
311 expected: offset + length,
312 found: bytes.len(),
313 });
314 }
315
316 let string_val = std::str::from_utf8(&bytes[offset..offset + length])
317 .map_err(|_| BinaryError::InvalidUtf8 { field_id: fid })?
318 .to_string();
319 offset += length;
320 strings.push(string_val);
321 }
322
323 BinaryValue::StringArray(strings)
324 }
325 };
326
327 Ok((Self { fid, tag, value }, offset))
328 }
329}
330
331#[cfg(test)]
332mod tests {
333 #![allow(clippy::approx_constant)]
334
335 use super::*;
336 use lnmp_core::LnmpValue;
337
338 #[test]
339 fn test_from_field_int() {
340 let field = LnmpField {
341 fid: 12,
342 value: LnmpValue::Int(14532),
343 };
344
345 let entry = BinaryEntry::from_field(&field).unwrap();
346 assert_eq!(entry.fid, 12);
347 assert_eq!(entry.tag, TypeTag::Int);
348 assert_eq!(entry.value, BinaryValue::Int(14532));
349 }
350
351 #[test]
352 fn test_from_field_float() {
353 let field = LnmpField {
354 fid: 5,
355 value: LnmpValue::Float(3.14),
356 };
357
358 let entry = BinaryEntry::from_field(&field).unwrap();
359 assert_eq!(entry.fid, 5);
360 assert_eq!(entry.tag, TypeTag::Float);
361 assert_eq!(entry.value, BinaryValue::Float(3.14));
362 }
363
364 #[test]
365 fn test_from_field_bool() {
366 let field = LnmpField {
367 fid: 7,
368 value: LnmpValue::Bool(true),
369 };
370
371 let entry = BinaryEntry::from_field(&field).unwrap();
372 assert_eq!(entry.fid, 7);
373 assert_eq!(entry.tag, TypeTag::Bool);
374 assert_eq!(entry.value, BinaryValue::Bool(true));
375 }
376
377 #[test]
378 fn test_from_field_string() {
379 let field = LnmpField {
380 fid: 1,
381 value: LnmpValue::String("hello".to_string()),
382 };
383
384 let entry = BinaryEntry::from_field(&field).unwrap();
385 assert_eq!(entry.fid, 1);
386 assert_eq!(entry.tag, TypeTag::String);
387 assert_eq!(entry.value, BinaryValue::String("hello".to_string()));
388 }
389
390 #[test]
391 fn test_from_field_string_array() {
392 let field = LnmpField {
393 fid: 23,
394 value: LnmpValue::StringArray(vec!["admin".to_string(), "dev".to_string()]),
395 };
396
397 let entry = BinaryEntry::from_field(&field).unwrap();
398 assert_eq!(entry.fid, 23);
399 assert_eq!(entry.tag, TypeTag::StringArray);
400 assert_eq!(
401 entry.value,
402 BinaryValue::StringArray(vec!["admin".to_string(), "dev".to_string()])
403 );
404 }
405
406 #[test]
407 fn test_to_field_int() {
408 let entry = BinaryEntry {
409 fid: 12,
410 tag: TypeTag::Int,
411 value: BinaryValue::Int(42),
412 };
413
414 let field = entry.to_field();
415 assert_eq!(field.fid, 12);
416 assert_eq!(field.value, LnmpValue::Int(42));
417 }
418
419 #[test]
420 fn test_to_field_float() {
421 let entry = BinaryEntry {
422 fid: 5,
423 tag: TypeTag::Float,
424 value: BinaryValue::Float(2.718),
425 };
426
427 let field = entry.to_field();
428 assert_eq!(field.fid, 5);
429 assert_eq!(field.value, LnmpValue::Float(2.718));
430 }
431
432 #[test]
433 fn test_to_field_bool() {
434 let entry = BinaryEntry {
435 fid: 7,
436 tag: TypeTag::Bool,
437 value: BinaryValue::Bool(false),
438 };
439
440 let field = entry.to_field();
441 assert_eq!(field.fid, 7);
442 assert_eq!(field.value, LnmpValue::Bool(false));
443 }
444
445 #[test]
446 fn test_to_field_string() {
447 let entry = BinaryEntry {
448 fid: 1,
449 tag: TypeTag::String,
450 value: BinaryValue::String("world".to_string()),
451 };
452
453 let field = entry.to_field();
454 assert_eq!(field.fid, 1);
455 assert_eq!(field.value, LnmpValue::String("world".to_string()));
456 }
457
458 #[test]
459 fn test_to_field_string_array() {
460 let entry = BinaryEntry {
461 fid: 23,
462 tag: TypeTag::StringArray,
463 value: BinaryValue::StringArray(vec!["x".to_string(), "y".to_string()]),
464 };
465
466 let field = entry.to_field();
467 assert_eq!(field.fid, 23);
468 assert_eq!(
469 field.value,
470 LnmpValue::StringArray(vec!["x".to_string(), "y".to_string()])
471 );
472 }
473
474 #[test]
475 fn test_encode_int() {
476 let entry = BinaryEntry {
477 fid: 12,
478 tag: TypeTag::Int,
479 value: BinaryValue::Int(14532),
480 };
481
482 let bytes = entry.encode();
483
484 assert_eq!(bytes[0], 0x0C);
486 assert_eq!(bytes[1], 0x00);
487 assert_eq!(bytes[2], 0x01);
489 let varint_bytes = varint::encode(14532);
491 assert_eq!(&bytes[3..], &varint_bytes[..]);
492 }
493
494 #[test]
495 fn test_encode_float() {
496 let entry = BinaryEntry {
497 fid: 5,
498 tag: TypeTag::Float,
499 value: BinaryValue::Float(3.14),
500 };
501
502 let bytes = entry.encode();
503
504 assert_eq!(bytes[0], 0x05);
506 assert_eq!(bytes[1], 0x00);
507 assert_eq!(bytes[2], 0x02);
509 let float_bytes = 3.14f64.to_le_bytes();
511 assert_eq!(&bytes[3..11], &float_bytes[..]);
512 }
513
514 #[test]
515 fn test_encode_bool_true() {
516 let entry = BinaryEntry {
517 fid: 7,
518 tag: TypeTag::Bool,
519 value: BinaryValue::Bool(true),
520 };
521
522 let bytes = entry.encode();
523
524 assert_eq!(bytes[0], 0x07);
526 assert_eq!(bytes[1], 0x00);
527 assert_eq!(bytes[2], 0x03);
529 assert_eq!(bytes[3], 0x01);
531 }
532
533 #[test]
534 fn test_encode_bool_false() {
535 let entry = BinaryEntry {
536 fid: 7,
537 tag: TypeTag::Bool,
538 value: BinaryValue::Bool(false),
539 };
540
541 let bytes = entry.encode();
542
543 assert_eq!(bytes[0], 0x07);
545 assert_eq!(bytes[1], 0x00);
546 assert_eq!(bytes[2], 0x03);
548 assert_eq!(bytes[3], 0x00);
550 }
551
552 #[test]
553 fn test_encode_string() {
554 let entry = BinaryEntry {
555 fid: 1,
556 tag: TypeTag::String,
557 value: BinaryValue::String("hello".to_string()),
558 };
559
560 let bytes = entry.encode();
561
562 assert_eq!(bytes[0], 0x01);
564 assert_eq!(bytes[1], 0x00);
565 assert_eq!(bytes[2], 0x04);
567 let length_varint = varint::encode(5);
569 assert_eq!(&bytes[3..3 + length_varint.len()], &length_varint[..]);
570 let offset = 3 + length_varint.len();
571 assert_eq!(&bytes[offset..], b"hello");
572 }
573
574 #[test]
575 fn test_encode_string_array() {
576 let entry = BinaryEntry {
577 fid: 23,
578 tag: TypeTag::StringArray,
579 value: BinaryValue::StringArray(vec!["admin".to_string(), "dev".to_string()]),
580 };
581
582 let bytes = entry.encode();
583
584 assert_eq!(bytes[0], 0x17);
586 assert_eq!(bytes[1], 0x00);
587 assert_eq!(bytes[2], 0x05);
589
590 let mut offset = 3;
591 let count_varint = varint::encode(2);
593 assert_eq!(
594 &bytes[offset..offset + count_varint.len()],
595 &count_varint[..]
596 );
597 offset += count_varint.len();
598
599 let len1_varint = varint::encode(5);
601 assert_eq!(&bytes[offset..offset + len1_varint.len()], &len1_varint[..]);
602 offset += len1_varint.len();
603 assert_eq!(&bytes[offset..offset + 5], b"admin");
604 offset += 5;
605
606 let len2_varint = varint::encode(3);
608 assert_eq!(&bytes[offset..offset + len2_varint.len()], &len2_varint[..]);
609 offset += len2_varint.len();
610 assert_eq!(&bytes[offset..offset + 3], b"dev");
611 }
612
613 #[test]
614 fn test_decode_int() {
615 let entry = BinaryEntry {
616 fid: 12,
617 tag: TypeTag::Int,
618 value: BinaryValue::Int(14532),
619 };
620
621 let bytes = entry.encode();
622 let (decoded, consumed) = BinaryEntry::decode(&bytes).unwrap();
623
624 assert_eq!(decoded, entry);
625 assert_eq!(consumed, bytes.len());
626 }
627
628 #[test]
629 fn test_decode_float() {
630 let entry = BinaryEntry {
631 fid: 5,
632 tag: TypeTag::Float,
633 value: BinaryValue::Float(3.14),
634 };
635
636 let bytes = entry.encode();
637 let (decoded, consumed) = BinaryEntry::decode(&bytes).unwrap();
638
639 assert_eq!(decoded, entry);
640 assert_eq!(consumed, bytes.len());
641 }
642
643 #[test]
644 fn test_decode_bool() {
645 let entry = BinaryEntry {
646 fid: 7,
647 tag: TypeTag::Bool,
648 value: BinaryValue::Bool(true),
649 };
650
651 let bytes = entry.encode();
652 let (decoded, consumed) = BinaryEntry::decode(&bytes).unwrap();
653
654 assert_eq!(decoded, entry);
655 assert_eq!(consumed, bytes.len());
656 }
657
658 #[test]
659 fn test_decode_string() {
660 let entry = BinaryEntry {
661 fid: 1,
662 tag: TypeTag::String,
663 value: BinaryValue::String("hello".to_string()),
664 };
665
666 let bytes = entry.encode();
667 let (decoded, consumed) = BinaryEntry::decode(&bytes).unwrap();
668
669 assert_eq!(decoded, entry);
670 assert_eq!(consumed, bytes.len());
671 }
672
673 #[test]
674 fn test_decode_string_array() {
675 let entry = BinaryEntry {
676 fid: 23,
677 tag: TypeTag::StringArray,
678 value: BinaryValue::StringArray(vec!["admin".to_string(), "dev".to_string()]),
679 };
680
681 let bytes = entry.encode();
682 let (decoded, consumed) = BinaryEntry::decode(&bytes).unwrap();
683
684 assert_eq!(decoded, entry);
685 assert_eq!(consumed, bytes.len());
686 }
687
688 #[test]
689 fn test_decode_with_trailing_data() {
690 let entry = BinaryEntry {
691 fid: 1,
692 tag: TypeTag::Int,
693 value: BinaryValue::Int(42),
694 };
695
696 let mut bytes = entry.encode();
697 bytes.extend_from_slice(&[0xFF, 0xFF, 0xFF]); let (decoded, consumed) = BinaryEntry::decode(&bytes).unwrap();
700
701 assert_eq!(decoded, entry);
702 assert_eq!(consumed, bytes.len() - 3); }
704
705 #[test]
706 fn test_decode_insufficient_data_fid() {
707 let bytes = vec![0x01]; let result = BinaryEntry::decode(&bytes);
709 assert!(matches!(result, Err(BinaryError::UnexpectedEof { .. })));
710 }
711
712 #[test]
713 fn test_decode_insufficient_data_tag() {
714 let bytes = vec![0x01, 0x00]; let result = BinaryEntry::decode(&bytes);
716 assert!(matches!(result, Err(BinaryError::UnexpectedEof { .. })));
717 }
718
719 #[test]
720 fn test_decode_invalid_type_tag() {
721 let bytes = vec![0x01, 0x00, 0xFF]; let result = BinaryEntry::decode(&bytes);
723 assert!(matches!(result, Err(BinaryError::InvalidTypeTag { .. })));
724 }
725
726 #[test]
727 fn test_decode_invalid_bool_value() {
728 let bytes = vec![0x01, 0x00, 0x03, 0x02]; let result = BinaryEntry::decode(&bytes);
730 assert!(matches!(result, Err(BinaryError::InvalidValue { .. })));
731 }
732
733 #[test]
734 fn test_decode_invalid_utf8() {
735 let mut bytes = vec![0x01, 0x00, 0x04]; bytes.extend_from_slice(&varint::encode(3)); bytes.extend_from_slice(&[0xFF, 0xFE, 0xFD]); let result = BinaryEntry::decode(&bytes);
740 assert!(matches!(result, Err(BinaryError::InvalidUtf8 { .. })));
741 }
742
743 #[test]
744 fn test_roundtrip_all_types() {
745 let test_cases = vec![
746 BinaryEntry {
747 fid: 1,
748 tag: TypeTag::Int,
749 value: BinaryValue::Int(-42),
750 },
751 BinaryEntry {
752 fid: 2,
753 tag: TypeTag::Float,
754 value: BinaryValue::Float(3.14159),
755 },
756 BinaryEntry {
757 fid: 3,
758 tag: TypeTag::Bool,
759 value: BinaryValue::Bool(true),
760 },
761 BinaryEntry {
762 fid: 4,
763 tag: TypeTag::String,
764 value: BinaryValue::String("test".to_string()),
765 },
766 BinaryEntry {
767 fid: 5,
768 tag: TypeTag::StringArray,
769 value: BinaryValue::StringArray(vec!["a".to_string(), "b".to_string()]),
770 },
771 ];
772
773 for entry in test_cases {
774 let bytes = entry.encode();
775 let (decoded, _) = BinaryEntry::decode(&bytes).unwrap();
776 assert_eq!(decoded, entry);
777 }
778 }
779
780 #[test]
781 fn test_fid_boundary_values() {
782 let entry0 = BinaryEntry {
784 fid: 0,
785 tag: TypeTag::Int,
786 value: BinaryValue::Int(1),
787 };
788 let bytes0 = entry0.encode();
789 let (decoded0, _) = BinaryEntry::decode(&bytes0).unwrap();
790 assert_eq!(decoded0.fid, 0);
791
792 let entry_max = BinaryEntry {
794 fid: 65535,
795 tag: TypeTag::Int,
796 value: BinaryValue::Int(1),
797 };
798 let bytes_max = entry_max.encode();
799 let (decoded_max, _) = BinaryEntry::decode(&bytes_max).unwrap();
800 assert_eq!(decoded_max.fid, 65535);
801 }
802
803 #[test]
804 fn test_empty_string() {
805 let entry = BinaryEntry {
806 fid: 1,
807 tag: TypeTag::String,
808 value: BinaryValue::String("".to_string()),
809 };
810
811 let bytes = entry.encode();
812 let (decoded, _) = BinaryEntry::decode(&bytes).unwrap();
813 assert_eq!(decoded, entry);
814 }
815
816 #[test]
817 fn test_empty_string_array() {
818 let entry = BinaryEntry {
819 fid: 1,
820 tag: TypeTag::StringArray,
821 value: BinaryValue::StringArray(vec![]),
822 };
823
824 let bytes = entry.encode();
825 let (decoded, _) = BinaryEntry::decode(&bytes).unwrap();
826 assert_eq!(decoded, entry);
827 }
828
829 #[test]
830 fn test_string_with_unicode() {
831 let entry = BinaryEntry {
832 fid: 1,
833 tag: TypeTag::String,
834 value: BinaryValue::String("Hello 🎯 World".to_string()),
835 };
836
837 let bytes = entry.encode();
838 let (decoded, _) = BinaryEntry::decode(&bytes).unwrap();
839 assert_eq!(decoded, entry);
840 }
841
842 #[test]
843 fn test_negative_int() {
844 let entry = BinaryEntry {
845 fid: 1,
846 tag: TypeTag::Int,
847 value: BinaryValue::Int(-9999),
848 };
849
850 let bytes = entry.encode();
851 let (decoded, _) = BinaryEntry::decode(&bytes).unwrap();
852 assert_eq!(decoded, entry);
853 }
854
855 #[test]
856 fn test_special_floats() {
857 let entry_nan = BinaryEntry {
859 fid: 1,
860 tag: TypeTag::Float,
861 value: BinaryValue::Float(f64::NAN),
862 };
863 let bytes_nan = entry_nan.encode();
864 let (decoded_nan, _) = BinaryEntry::decode(&bytes_nan).unwrap();
865 match decoded_nan.value {
866 BinaryValue::Float(f) => assert!(f.is_nan()),
867 _ => panic!("Expected Float variant"),
868 }
869
870 let entry_inf = BinaryEntry {
872 fid: 2,
873 tag: TypeTag::Float,
874 value: BinaryValue::Float(f64::INFINITY),
875 };
876 let bytes_inf = entry_inf.encode();
877 let (decoded_inf, _) = BinaryEntry::decode(&bytes_inf).unwrap();
878 assert_eq!(decoded_inf, entry_inf);
879
880 let entry_neg_inf = BinaryEntry {
882 fid: 3,
883 tag: TypeTag::Float,
884 value: BinaryValue::Float(f64::NEG_INFINITY),
885 };
886 let bytes_neg_inf = entry_neg_inf.encode();
887 let (decoded_neg_inf, _) = BinaryEntry::decode(&bytes_neg_inf).unwrap();
888 assert_eq!(decoded_neg_inf, entry_neg_inf);
889 }
890}